The native export parser throws one BinaryResourceFailure for both its
262144-entry inventory ceiling and its 16 MiB retained-text byte budget, and
NativeExportsProvider mapped every such refusal to the fixed-count recovery.
A PE whose export names exhaust the byte budget therefore reported
reported_limits.maximum 16777216 next to "is a fixed count".
Tag each parser allowance at the producing boundary (NativeExportLimitFailure
with limit "rows" or "retained_text") and let the provider select count,
byte, or structural-decoding recovery from that tag instead of from message
text. The refusal code, non-retryable flag, message, and reported maximum are
unchanged.
Fixes#7628
Supersedes #7754
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>
The darwin-only acceptance test passes the caller's environment to the CLI
and points only Hopper, Ghidra and Java at missing paths. On macOS the
list_names fallback has four candidates (ghidra, hopper, ida, kuna), so a
REA_IDA_MCP_CONFIG or REA_KUNA_COMMAND set in the developer's shell still
reaches it: with REA_KUNA_COMMAND set, kuna is no longer rejected as
not_configured. Point both at missing paths, as
tests/acceptance/nativeDispatchSnapshot.test.ts does, so the test always
exercises the unavailable fallback.
Signed-off-by: Zhaowei Gu <83746079+zw-g@users.noreply.github.com>
Refs #7651
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>
The key resolver followed slice members, but the explicit-stack hashability
walk skipped them, so a code object reached through a slice constant started
a recursive hashability check. A 3,000-link slice-wrapped TYPE_REF code chain
overflowed the JavaScript stack. Push slice members onto the same explicit
stack as tuple and frozenset members.
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>
The in-process equivalence checks share every module that the complete
CLI already imported, so they cannot detect a registrar that relies on
another module's import-time setup. For each registrar, a fresh rea
process now runs one of its commands with an unknown option, taking the
lazy path. The test compares the rejection document and status with the
complete CLI's.
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>
Stryker's TypeScript checker compiles the test support without
vitest.config.ts, so inject("testDeadlineScale") had type never there.
Outside a test the wait helper now uses the unscaled source deadline,
which no project's hook deadline is shorter than.
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>
process.exit() shuts Node's platform down without tearing the V8
isolate down. When a concurrent Maglev or baseline compile job is
waiting for a collection at that moment, the main thread blocks forever
in NodePlatform::Shutdown joining it (captured with gdb on Node
24.22.1). A one-shot command that called Incur's exit then never
terminated: about 1 in 20 such exits after the lazy CLI loading change,
and rarely on main.
The exit callback now sets process.exitCode and lets the event loop
drain, so Node tears the isolate down in order. A handle that outlives a
one-second grace still gets the forced exit with the same status.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The MCP universal-slice refusal test also compared whole English
messages; it now checks the architecture input issue and only the
offered selector. The linker-options CLI test drops its per-call child
timeout, which the testing guide reserves for testing the deadline.
Refs #9792
Refs #8935
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The chained-import CLI test ran xcrun through a bare execFile, outside
the test's process registry, so a stalled compiler or dyld_info could
outlive the test; it now uses the processes fixture. The slice
selection refusal tests compared whole English messages; they now check
the refusal kind, the offered selector, and that the selector works.
Refs #8723
Refs #9792
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
dyld_info prints chained-fixup rows by import ordinal, and a row with two
spaces after the ordinal has two readings. REA settled them against the
nm undefined-symbol list, which omits weak-def coalesced names, so such
imports got null or ambiguous names. inspect-macho now reads the
chained-fixup import table from the binary and matches rows by ordinal,
falling back to the symbol table with a recorded limitation when the
table is unusable.
Fixes#8723
Squashed from #8724 and rebased onto main.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
inspect-macho marked fully decoded LC_LINKER_OPTION, LC_NOTE and
LC_FILESET_ENTRY commands as undecoded. Each now counts as decoded only
when its payload is consumed exactly (the fileset string must start
right after the 32-byte header and end at cmdsize), and the note keeps
its full owner storage.
Fixes#8935
Squashed from #8937 and rebased onto main.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Move the transient stat case into HostFileRead.test.ts behind a
pass-through fs mock (only one fixture name fails), instead of a
separate module-mocked file.
Refs #9703
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
readSpan added a member's bytes to memberBytesRead only after the whole
range read succeeded, so a read that consumed some bytes and then
failed (for example EIO) charged nothing against the packaged-probe
allowance. Charge the cumulative bytes from readFileHandleRange's
checkpoint as they arrive.
Also cover the transient stat failure that HostFileRead's test named
but never induced: EIO now has its own module-mocked test, and the
original case is renamed for what it checks.
Refs #10443
Refs #9703
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 native UI verifier now removes its fixture root only after `open -W`
exits on its own (67ce671d66). The lane test's `open` stand-in stayed
alive until the test released it, so every case waited out the grace
period, retained the root and failed on the Apple E2E job. The stand-in
now exits when its fixture exits, as `open -W` does.
The shared-descendant pyc case bounded wall-clock time at 5 s; it runs in
~0.5 s locally but 4-7 s on loaded CI shards and failed scheduled runs.
The retained-heap bound and exact object counts already detect the
per-wrapper copy regression, so the host-speed assertion is removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since #8444 the completed observation is projected once at the composed
error's details.partial_observation rather than inside primary_error,
so restore #7319's retained-Evidence assertion there.
Refs #7279
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The testing guide asks for structured facts rather than frozen
sentences or banned phrases. The existing mutatesDevice declarations and
push receipt assertions already cover the behavior; the doc-comment
correction stays.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main now reports a descriptor close failure as unreadable_output without
the completed partial observation, so the retained-Evidence assertion
from the original branch no longer describes current behavior. Keep the
provider-id regression this fix owns; the dropped partial observation is
tracked separately.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A launcher whose exec is refused by an operating-system security policy
surfaces EPERM, not EACCES. It was reported as a missing launcher, so
the recovery pointed at installing apktool instead of fixing execute
permission. EPERM now joins EACCES as command_not_executable.
Squashed from #5180 and rebased onto main.
Supersedes #5180 (follow-up to #5177)
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The push_adb_file contract text already describes the tool as
device-mutating after #2990, but the AdbProvider class comment still called
the caller-requested file push the only device mutation.
Correct that comment and guard the invariant with tests: no tool contract
may claim to be the only device-mutating operation, and push_adb_file
reports its device mutation with and without device-side sha256sum
verification.
Refs #2602.
Supersedes #2868 (follow-up to #2602)
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comparing retained scenario captures flattened each side's unique step
map, so a step_id duplicated on one side vanished from that side's map;
the same id arriving uniquely on the other side then landed in
before_only/after_only and produced a missing_before_step or
missing_after_step failure for a step the duplicate side still retains.
The comparison reported both the duplicate and a definite absence for
the same id, a stronger claim than the ambiguity supports.
Alignment now keeps a duplicated id out of the absence lists on both
sides: the id stays unaligned with its duplicate failure, but no capture
is described as missing a step it retains. Genuinely missing ids keep
their missing_* classification and absence lists.
Fixes#7415
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
inspect-byte-entropy passed a hard-coded "rea-byte-entropy" to the shared command finalizer, so a failed descriptor close named a provider that differs from the Evidence provider ("byte-entropy"). Use BYTE_ENTROPY_PROVIDER.id so both come from one owner.
Fixes#7279
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.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>
Extend readmeConsistency.test.ts with a Malayalam case mirroring the
existing Persian one, addressing the P2 review finding on #6383. The
update heading's U+200C is written as an explicit escape so an editor
cannot strip it invisibly; verified the test fails when the joiner is
removed from README_ml.md.
npm run test:local -- tests/conformance/readmeConsistency.test.ts
passes 10/10.
Supersedes #6383 (follow-up to #6731)
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 registration repair guide named 24 of the 29 client IDs that
`rea setup --client` accepts. Add codebuddy, cline, kimi, workbuddy and
lm_studio, and make the documentation-facts check require every setup
client ID in that list so a new client cannot be omitted again.
Regenerate the tracked Cursor plugin copy of the reference.
Fixes#7640
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
The 6.6.0 "ADB observations and transfers" bullet thanks @Copilot, an
automation account that scripts/lib/release-notes.mjs excludes from
human credit. The current checker rejects the retained section with
"Unverified human credit @copilot". Remove that handle from the thanks
list; the human contributors and the contribution inventory stay as
they are.
Fixes#7674
Supersedes #7755
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>