Commit Graph
3691 Commits
Author SHA1 Message Date
morluto e83e3fa8a0 feat(errors): type refusals at the producer with a total recovery (#10577)
* feat(errors): type refusals at the producer with a total recovery

A resource refusal without authored text fell back to resource-kind advice:
a fixed parser ceiling reported as memory told the caller to add host
memory, an upstream IDA reply ceiling pointed at REA's MCP transport, and a
fixed Kuna text ceiling reported as capacity was marked retryable. An
ambiguous selector was reported as invalid input that pointed at the schema.

Add AnalysisRefusal with three variants built from facts producers already
own: fixed_ceiling (FixedAllowance, now with limit, unit and narrowing),
adjustable_budget (AnalysisSettingLimit) and ambiguous_selector (new
AnalysisInputError option). Each variant is attributed to the error's
operation and projected under details.refusal. Presentation is a total
switch over the variants, and authored text still takes precedence.

Migrate the first producers. GraphQL nesting, Playwright trace input, the
Kuna function text and the IDA upstream reply become fixed ceilings. jadx
overloads and Kuna ambiguous names become ambiguous selectors, replacing the
two Kuna-specific ambiguity texts. Seven occupied admissions declare
measuredExhaustion. The rea/typed-resource-refusal lint rule rejects new
untyped resource constraints, and the remaining 24 are counted in a baseline
that can only shrink.

* fix(errors): honor refusal recovery ownership
2026-11-14 14:36:14 -05:00
morluto 81c115b4c3 fix(setup): register mcp add clients from the shared client table (#10591)
Table-backed add-mcp agents now project their client-table row instead of
redeclaring format, display name and profile in a second table. The row
also carries add-mcp aliases and project documents. mcp add now applies
the read-scope rules setup already enforced: Gemini settings policy blocks,
the Claude Desktop MSIX write blocker and MSIX AppData redirection.
2026-11-14 14:14:09 -05:00
morluto a874fcc4e3 refactor(javascript): classify implicit execution in one owner (#10605)
* refactor(javascript): classify implicit execution in one owner

Add javascriptSemanticExecutionPoints, a total classification of every
runtime Babel node type into the ways its evaluation can run code without
call syntax. The member-mutation escape walk, the accessor operand
collector and the catch-source reachability check consult it instead of
their own syntax lists. Kinds those collectors have never applied are now
named in exhaustive switches rather than absent.

A guard test fails when the installed @babel/types defines a node type the
table does not classify, and unknown node types classify as unsupported
syntax rather than inert.

* test(hopper): retry cleanup after confirmed application exit

* fix(javascript): classify enumeration and catch binding effects

* fix(javascript): retain catch uncertainty for identifier reads
2026-11-14 14:13:07 -05:00
morluto 4502bd44bb fix(gdb): keep a retained cancelled startup a cancellation on cleanup retry (#10551)
A cancelled GDB startup whose process stop could not be confirmed retained a
capability error. The next cleanup retry then reported "This analysis is
unavailable for the current target" instead of the caller's cancellation.

Move Rizin's retention rule (the #5963 fix) into one shared
retainedDebuggerCleanupFailure in src/process/ownedDebuggerSession.ts and use
it from both session managers. The GDB command-cancel path now retains the
cancellation itself, so retry reports no longer depend on Set insertion order.
2026-11-14 13:28:43 -05:00
gensokyo-devandgensokyo-dev 583bb477c1 test(inspector): keep the sibling Node discovery fixtures out of underscored roots
Use createNodeDiscoveryTempDirectory for the target-location and
runtime-observation fixtures too, so a TMPDIR containing `_` cannot make
them fail for the same reason as the cancellation test.

Refs #9996

The sibling sites are the ones #4484 switched.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 17:59:38 +01:00
Hafeez Shaikhandgensokyo-dev fc4c319cb4 test(ines): make same-size prefix changes visible on coarse timestamps
The changed-prefix regression rewrote its fixture at the same size within
milliseconds of creating it. Linux stamps mtime/ctime from a coarse clock,
so both writes can share every stat field the target guard compares, and the
classifier parsed the rewritten header without seeing a change. Age the
fixture's timestamps before the mutation so the rewrite is observable on any
filesystem while the test still requires a changed-input refusal.

Fixes #8685

Supersedes #8689

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 17:59:38 +01:00
Rudy Celekliandgensokyo-dev 85198fd5cb fix(pe): retain TLS templates without complete file backing
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

Fixes #7400
Supersedes #7529

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 16:31:24 +01:00
neoLsHandgensokyo-dev d7c73923d7 fix(model): count an empty innermost GGUF array against the frame limit
The nesting guard ran on a child visit of GgufHeader#value, so an empty
innermost array never produced one and a 33rd frame parsed as success
while the reported limit stayed maximum_array_frames: 32. Charge the
frame when entering the ARRAY branch instead, so the bound counts the
advertised unit and no longer depends on a scalar child that is not a
frame.

Fixes #7312

Supersedes #7698

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 16:31:24 +01:00
18b72ca461 fix(android): qualify the JNI library inventory by required splits
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>
2026-11-14 16:15:32 +01:00
101e0986b0 fix(setup): show non-interactive setup results in a terminal
Setup's result is agent-only, so incur hides it when stdout is a terminal and
no format was chosen. Only an interactive setup or a fully interactive TTY dry
run rendered a summary, so `rea setup --yes` printed nothing. Render the dry
run plan or the existing result summary under incur's own hidden-output
condition instead.

Fixes #10531
Supersedes #2185

Co-Authored-By: balkan16 <57933796+balkan16@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 16:06:23 +01:00
ducanhnguyen223andgensokyo-dev ba32cd3c28 fix(native): report an ownership-helper compile timeout as retryable
When the macOS process-ownership helper's swiftc compile hit
REA_SWIFTC_COMPILE_TIMEOUT_MS, inspect-macho and other native commands
reported a non-retryable provider failure, while process capture
already treated the same fact as retryable. The helper's error now owns
that interpretation (compilerTimedOut and compileTimeout, with its
deadline, message and recovery). Native commands return a retryable
AnalysisTimeoutError naming REA_SWIFTC_COMPILE_TIMEOUT_MS, and process
capture reads the same fact.

Fixes #8936
Supersedes #8938

Based on #8938; the interpretation moves to the error's owner so both
consumers share it.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 15:32:34 +01:00
Antrulyandgensokyo-dev f8fc5be364 fix(android): classify a pre-handshake JADX heap shortage as a resource limit
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>
2026-11-14 15:25:02 +01:00
0ffde0cd09 fix(desktop): admit a build witness folder by the record's own rule
The witness seed accepted its folder with a readdir check that follows
symlinks, treats a missing path as usable, and reports a regular-file
parent as "not empty". The record is later saved through planOutputTree,
so a seed could accept a folder the save then refused. The seed now
admits the folder with planOutputTree too, and returns its refusal.

Fixes #9291

The MCP boundary test is from #9292 by viniciusdsandrade; its parallel
admission helper is not taken, since planOutputTree already owns the
rule and export already uses it.

Co-Authored-By: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:59:49 +01:00
5e1d504664 fix(environment): admit the output root before creating its parents
environment-build/export ran an unclassified recursive mkdir of the
destination's parent before SafeOutputTree validated anything. A
trailing `..` therefore created directories before it was refused, and
a regular file in the parent path surfaced as unreadable_output instead
of refusing the selection.

SafeOutputTree.create gains a createParents option that admits the
root's own syntax first, then creates the parents, mapping EEXIST and
ENOTDIR to a destination refusal. The environment bundle writer uses it
instead of its own mkdir.

Fixes #7688
Fixes #7571

The non-directory mapping comes from #7734 by HeadmasterEggy, and the
syntax-first check from #7588 by harshitethic; their tests are kept.

Co-Authored-By: Avocado <headmastereggy@gmail.com>
Co-Authored-By: Harshit Sharma <66710144+harshitethic@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:59:49 +01:00
Vinícius DS Andradeandgensokyo-dev 34803c45ae test(web): use valid script_key format in bundle capacity test
Refs #10445

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:59:41 +01:00
Vinícius DS Andradeandgensokyo-dev 2032b5a819 fix(web): merge wide script analysis results without call spreads
Fixes #10445
Supersedes #10446

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:59:41 +01:00
gensokyo-devandgensokyo-dev 9d2a57fd8d fix(decompile): keep each successful batch item's own limitations
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>
2026-11-14 14:16:47 +01:00
d734e6424d fix(cli): advertise parsed JSON documents in --schema
`--schema` for JSON-input CLI commands showed only an opaque
`inputJson` string, so callers could not see the document the command
actually parses. The argument now carries the decoded document as its
contentSchema, built from the same contract each command or its service
parses with (the Evidence input frame, or the ledger and coverage
request schemas). `$schema` is stripped, and a schema JSON Schema cannot
represent is refused rather than advertised as {}.

Fixes #9195
Supersedes #9283

Squashed from #9283 (with morluto's validation test) and rebased onto
main; the coverage test now expects boundary_id's stable-identifier
pattern from #9919. #9214 by 1052326311 took the same approach.

Co-Authored-By: morluto <76467478+morluto@users.noreply.github.com>
Co-Authored-By: 1052326311 <65798732+1052326311@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
gensokyo-devandgensokyo-dev cf58037726 fix(setup): show a known manual step in the interactive dry run
The approval prompt now discloses a client's manual completion step,
but the interactive TTY dry run still printed only the planned file
changes, so `rea setup --dry-run --client grok_bot` hid the Grok Bot
connector step. The dry-run renderer now prints the planned result's
remediation the same way.

Refs #7692

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
Avocadoandgensokyo-dev bbad1db998 test(setup): admit inert launcher in Linux approval fixture
Refs #7692

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
Avocadoandgensokyo-dev 4d02bc82b3 fix(setup): disclose manual connector steps before approval
Fixes #7692
Supersedes #7792

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
70960d253d fix(mcp): traverse contentSchema in schema keyword normalization
Fixes #7123

Supersedes #7122

Co-authored-by: mawahnnie <198902683+mawahnnie@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
LexLuthorPrimeroandgensokyo-dev b6b6800346 fix(contracts): keep advertised full-profile patterns portable
Fixes #10389
Supersedes #10423

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
a02202aba2 fix(cli): count the full-output envelope for TOON/YAML token counts
With --token-count --full-output, TOON and YAML results were delegated
to Incur before the envelope-aware count branch, so Incur counted only
the selected data (13) instead of the emitted full document (31).
Keep that combination on the REA output boundary so the count covers
the envelope and metadata, matching the docs/cli.md contract. Bare
counts stay delegated to Incur and are unchanged.

Fixes #7271
Supersedes #7278

Co-authored-by: Saim Shafique <128062316+sx4im@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
ShuaixinHuangandgensokyo-dev 86799f919d fix(desktop): preserve ZIP member identity across bounded readers
Fixes #10172
Supersedes #10173

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:16:39 +01:00
gensokyo-devandgensokyo-dev a6f98e733e test(native): pair the truncated export count case with a stored table
Add a PE whose section stores every declared export slot, so the entry
allowance refusal is also shown for a structurally possible table, and use it
over MCP. Leave dispatch-test directory removal to its temporary fixture.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
gensokyo-devandgensokyo-dev 065fbec4b3 fix(session): select the registered entrypoint as the running runtime does
Node resolves its script entrypoint lexically, so a registered spelling that
crosses a symlink before `..` names the running file lexically, while Bun
follows native traversal (#8844). Select the expected server path with the
shared runtime-aware entrypoint normalizer before comparing it with the
running entrypoint, and fall back to file identity only when they differ.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
gensokyo-devandgensokyo-dev 982ea7fa9f test: drop a frozen bridge sentence and a pcap deadline override
Keep the bridge cursor-mismatch code check without copying its message, and
let the pcap relative-tool diagnostic use the shared child deadline, which it
does not test.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
gensokyo-devandgensokyo-dev 4ad1eb5beb fix(snapshot): locate entry diagnostics by collection and index
Each snapshot entry is validated alone, so its schema issue path started at
the entry. Prefix it with entries or workflow_entries and the entry index so
the reason names the entry to repair, and match the header case's issue
count without freezing the whole sentence.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
gensokyo-devandgensokyo-dev 612b330b3b test(native): keep the export entry-allowance case in its own group
Merging the native export capacity tests made one describe block exceed
the lint function-length limit.

Refs #7628

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
3ae21f9ff8 fix(evidence): name the noncanonical bundle sections
Any canonical-form mismatch reported "Evidence bundle manifests are not
canonical", so a bundle whose records were out of order, or whose
unknowns differed, blamed unchanged manifests. The error now names the
top-level sections that differ from canonical form, for example
"Evidence bundle sections are not canonical: records".

Fixes #7330

Based on #7358 by zzrs-xxxr, which split records from manifests; this
reports every differing section instead, so unknowns or several
sections are attributed correctly.

Co-Authored-By: zzrs-xxxr <225415@qq.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
morlutoandgensokyo-dev 4104f88b62 fix(native-ui): advertise capture source requirement
Refs #7570

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
morlutoandgensokyo-dev 4d544c8434 test(snapshot): assert full validation diagnostics
Refs #7442

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
wunianze666-netizenandgensokyo-dev 213fcc8ce1 fix(snapshot): retain schema diagnostics in file failures
Refs morluto/rea#7442

Fixes #7442
Supersedes #7875

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
morlutoandgensokyo-dev 7471b07a90 test(native): verify export allowance recovery over MCP
Refs #7628

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
ayobamiseunandgensokyo-dev 8e5e23c21e fix(native): name the exhausted native export allowance by its units
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>
2026-11-14 14:06:23 +01:00
3a1db29166 fix(native): retain the dispatch reader failure when the symbol fallback fails
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>
2026-11-14 14:06:23 +01:00
fd97d0926c fix(hopper): type the Apple Events authorization denial
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>
2026-11-14 14:06:23 +01:00
1052326311andgensokyo-dev eee8c5fa97 fix(session): compare entrypoint file identity
Fixes #8844
Supersedes #8849

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
morlutoandgensokyo-dev 90fd58d373 test(pcap): verify relative tool diagnostics through MCP
Refs #7569

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
Harshit Sharmaandgensokyo-dev 1327c386da fix(pcap): keep selected relative executable paths in error facts (#7569)
Fixes #7569
Supersedes #7577

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 14:06:23 +01:00
gensokyo-devandgensokyo-dev 5451d3cb2d test(cli): compare each registrar in a fresh lazy process
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>
2026-11-14 20:25:11 +08:00
gensokyo-devandgensokyo-dev b990eb496d perf(cli): load only the registrar a one-shot command needs
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>
2026-11-14 20:25:11 +08:00
gensokyo-devandgensokyo-dev 55c9e8e546 test: close the wait-deadline review gaps
- 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>
2026-11-14 19:28:38 +08:00
gensokyo-devandgensokyo-dev 07e4b700ac test: let the deadline policy own test waits
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>
2026-11-14 19:28:38 +08:00
gensokyo-devandgensokyo-dev 054fbc4c26 fix(cli): exit one-shot commands by draining the event loop
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>
2026-11-14 19:28:31 +08:00
gensokyo-devandgensokyo-dev c169e8d56e test(native): assert universal slice refusals by their input issue
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>
2026-11-14 12:13:56 +01:00
gensokyo-devandgensokyo-dev 6a2d1dc066 test(native): own Mach-O test children and assert refusal facts
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>
2026-11-14 12:13:56 +01:00
Lewis Wongandgensokyo-dev 4bdd6d10c9 fix(native): name chained imports from the binary's import table
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>
2026-11-14 12:13:56 +01:00
ducanhnguyen223andgensokyo-dev 364432d6c9 fix(native): correct Mach-O command completeness
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>
2026-11-14 12:13:56 +01:00