Commit Graph
3717 Commits
Author SHA1 Message Date
morluto 44fedc8fdd fix(pcap): report a refused tool launch as an unavailable tool (#10553)
* fix(pcap): report a refused tool launch as an unavailable tool

When a capture read's tool launch was refused with EPERM, pcap reported it
as unreadable tool output (AnalysisProtocolError) instead of an unavailable
tool. Pcap also never told "not executable" apart from "missing".

Add classifyLaunchFailure in src/process as the one owner of which spawn
errnos mean missing (ENOENT, ENOTDIR) and which mean present but not
executable (EACCES, EPERM, ENOEXEC, EISDIR). Pcap, apktool and gdb used three
different errno lists; all three now use it.

* refactor(process): classify Java and adb launch refusals with the shared owner (#10598)

The Ghidra and JADX Java probes and adb's version probe now take
missing-versus-not-executable from classifyLaunchFailure instead of their
own errno checks. ELOOP and ENAMETOOLONG join the owner's missing set, so
adb keeps its existing classification and both Java probes now treat a
non-directory path component as a missing runtime.

* fix(pcap): preserve command launch attribution

* test(pcap): expect an unknown failing stage when a limited capture tool exits unsuccessfully

* fix(pcap): attribute a limited capture's exit through the prlimit wrapper

* fix(process): identify the refused executable for every launcher shape

Name the executable on errnos Node throws synchronously from spawn
(ENOEXEC, ENOTDIR, ...) and read the Windows native launcher's
executable-launch constraint, so pcap attributes those refusals to the
selected tool or limiter instead of an unknown stage.

* test(pcap): prove synchronous launch naming with ENOTDIR on every POSIX host
2026-11-14 21:11:59 -05:00
morluto 47925f3bef fix(browser): type screenshot, WebMCP and domain toggle CDP replies (#10647) 2026-11-14 21:11:43 -05:00
morluto 3a29b6b8ea refactor(il2cpp): report format failures through ParseFailure (#10701) 2026-11-14 21:11:29 -05:00
morluto cd5ea9a9fb fix(hopper): name the failing fields when a bridge reply misses its contract (#10713)
* fix(hopper): name the failing fields when a bridge reply misses its contract

* fix(ci): run the package baseline when the fake Hopper bridge changes

* fix(hopper): name nested union failures and cover every native schema in the package scope
2026-11-14 21:11:08 -05:00
morluto 0e662ac8bd fix(artifacts): classify ELF and thin Mach-O only when their headers decode (#10650)
* fix(artifacts): classify ELF and thin Mach-O only when their headers decode

Inventory classified a file as elf or mach-o on its magic number alone,
while target resolution requires a decodable ELF fixed header and a
walkable Mach-O load-command table. A magic-only stub or a Mach-O with
corrupt load commands was inventoried as an executable that open_binary
then refused. Both routes now share readNativeHeaderFormat; such files
are classified unknown.

* test(applications): give mobile application fixtures decodable native headers

Inventory now classifies ELF and thin Mach-O only when their headers decode, so the 8-byte magic stubs in the Android and Apple application fixtures no longer count as native code. Use the shared minimal header fixtures instead.
2026-11-15 09:52:48 +08:00
morluto e652f4409e fix(verify): rewrite counted baselines only when a count was lowered (#10669)
* fix(verify): rewrite counted baselines only when a count was lowered

* test(verify): own the baseline write decision in a tested helper
2026-11-15 09:42:02 +08:00
morluto 6f19681551 fix(browser): type DOM listener, metrics and emulation CDP replies (#10641)
* fix(browser): type CDP command replies and parse frame trees once

CdpConnection.send is typed by method name. A command registered in
src/browser/protocol/CdpCommands.ts has its parameters typed from the
protocol table Playwright ships and its reply parsed once by its own result
schema; a mismatch rejects that command with CdpMalformedReply
(protocol_error, command, JSON pointer) without poisoning the connection.
Playwright storage sessions admit replies through the same table.

Page.getFrameTree and Page.getResourceTree are the first registered
commands. Their one parser keeps per-frame facts tolerant (malformed child
entries remain explicit omissions) and replaces the per-site readers:
observeMainFrameUrl, mainFrameUrl, walkFrameTrees, frameTreeResources,
runtimeFrameTreeSchema and the scenario storage frame schema.

A reply without a frame tree used to be retried for two seconds and
reported as target_not_allowed; it is now one protocol_error.

A guard test counts literal CDP command names without a result schema per
source file; the baseline can only shrink.

* fix(browser): consume parsed CDP facts across boundaries

* refactor(browser): register target, storage and acknowledgement CDP replies

Register result schemas for Target.attachToTarget, Target.getTargetInfo,
Storage.getStorageKey, Page.addScriptToEvaluateOnNewDocument,
Debugger.setBreakpointByUrl, Debugger.evaluateOnCallFrame and fourteen
commands whose reply REA reads only as success. Their callers use the
parsed reply; the per-site readers are removed (attachedSessionId and the
scenario storage and service-worker zod schemas, which threw raw ZodError).

Playwright's Target.getTargetInfo in scenario attach now goes through the
same admission. The untyped-command baseline drops from 96 to 48.

* fix(browser): report malformed script source and coverage replies as protocol errors

* fix(browser): type DOM listener, metrics and emulation CDP replies

* fix(browser): report malformed script source and coverage replies as protocol errors (#10638)
2026-11-15 09:26:29 +08:00
morluto da53dce1f7 refactor(cli): project Go, V8 and delivery inspectors from their contracts (#10576)
Migrate inspect-go-binary, inspect-v8-code-cache, inspect-devicetree and
inspect-native-exports onto the contract command description and delete
their hand-written options and input spreads.

The description gains evidenceDelivery. It adds the shared --detail and
--evidence_output options, and the run context carries the selected
delivery. A contract detail field selects that delivery and is not passed
to the analysis, as the hand-written commands did. Go's cross-field
budget rules stay with the service's contract parse, so standalone
--max-string-literals still returns invalid_request.

The parity guard accepts the declared CLI-only delivery options as the
only options without a contract field.
2026-11-15 09:14:56 +08:00
morluto a11a54e797 fix(providers): treat undeclared bridge coverage and completion as unknown (#10651)
IDA's processor-neutral callgraph reader reported coverage complete when
upstream omitted the truncation flag or the per-function cap. Cutter
reported a command complete when a successful reply omitted
execution_state. Both now report unknown, so an omitted marker is never
read as a declaration of completeness.
2026-11-15 09:10:14 +08:00
morluto 6c062c9c2a fix(setup): stop writing the default compact input profile for Kimi and LM Studio (#10559)
* fix(setup): stop writing the default compact input profile for Kimi and LM Studio

The server already advertises compact input schemas when
REA_MCP_INPUT_SCHEMA_PROFILE is unset, so setup no longer adds that value to
Kimi Code and LM Studio registrations, and doctor/status no longer report a
registration without it as stale. Explicit stored or setup-environment
profiles are still preserved.

Refs #10514

* fix(setup): validate LM Studio registration environment

* test(hopper): retry cleanup after confirmed application exit
2026-11-14 19:01:15 -05:00
morluto f88d8964f9 fix(hopper): validate every bridge reply against one contract table (#10662)
* fix(hopper): validate inventory replies against their contracts at the provider edge

Hopper validated only the response envelope. list_names replies outside
the inventory contract were returned unchanged (projectHopperNameInventory
passed them through), and the regex search re-parsed its inventory with
its own policy. A per-method reply contract table built from the shared
native inventory schemas now validates list_names, list_procedures,
list_strings, search_procedures and search_strings once; a reply outside
the contract is an AnalysisOutputError. The remaining 31 operations are a
counted pending list that may only shrink.

* fix(hopper): add reply contracts for scalar, boolean and address-list operations

Twenty-two more Hopper operations are validated against reply contracts
built from the shared native schemas. The pending list shrinks from 31
to 9 operations.

* refactor(hopper): validate every bridge reply through one contract table

The reply table now covers every bridge method REA reads, including the
private caller-reconciliation methods. HopperFileOffset receives a
validated observation and HopperCallerReconciliation reads typed replies
instead of keeping its own schemas and re-parsing the native result. The
segment list schema moves from contracts into its domain owner.

* fix(hopper): apply reply contracts on the ready path and test every entry path

executeIfReady validated only list_procedures, so a malformed
list_documents reply could reach the completion path. Every contracted
operation is now validated there, and provider-level tests cover the
direct and ready paths for each inventory and document operation.
2026-11-14 18:59:39 -05:00
morluto a22fb6e60b fix(model): report malformed GGUF and Safetensors headers as invalid_format through ParseFailure (#10667)
* refactor(model): report GGUF and Safetensors format failures through ParseFailure

* fix(model): report malformed model headers as invalid_format through the shared mapping

Malformed and truncated GGUF and Safetensors headers now take the shared ParseFailure mapping (invalid_request, invalid_format on path) instead of the model provider's own BinaryTargetError file_format_rejected. Unsupported forms stay unsupported_target and model allowances keep their resource-constraint recovery.
2026-11-14 18:58:59 -05:00
morluto 2705aad365 fix(il2cpp): select universal binary slices through the shared Mach-O selection (#10661)
* fix(il2cpp): select universal binary slices through the shared Mach-O selection

* test(il2cpp): assert selection facts instead of full sentences
2026-11-14 18:58:48 -05:00
morluto 959af004df docs: refuse literal tool counts in living prose (#10585)
* docs: refuse literal tool counts in living prose

docs:check now refuses a count of ten or more tools in README, AGENTS,
CONTRIBUTING, docs/ (except dated releases, specs, verification and ADR
records), the authored skill and the public website. The catalog owns that
number and every hand-written copy goes stale when a tool is added. The three
current statements (240, 172 and 254 tools, all measured on earlier builds)
now refer to the catalog of the measured build instead.

* fix(docs): exclude generated pages from prose checks

* fix(docs): rerun the tool-count check when any scanned prose changes

The docs:check:built cache inputs and the CI docs lane did not cover AGENTS.md, CONTRIBUTING.md, every .agents/skills tree or website/public, so an edit there could reuse a cached pass or skip the docs job. The scanner now owns one isLivingProsePath predicate; the CI plan selects the docs lane with it, and a test binds the turbo inputs to the scanned roots.
2026-11-14 18:58:24 -05:00
morluto 3080a63729 fix(gpu): report malformed GPU containers as invalid_format (#10644)
fix(gpu): report malformed GPU containers as invalid_format through the shared parse-failure mapping

GpuCodeObjectsProvider mapped a malformed BinaryFormatFailure to a
BinaryTargetError (target_unavailable / file_format_rejected) while every
other format parser reports malformed bytes as an invalid path
(invalid_request / invalid_format). It now uses parseFailureAnalysisError.
2026-11-14 18:57:45 -05:00
morluto 3e9400873e refactor(browser): register target, storage and acknowledgement CDP replies (#10630)
* fix(browser): type CDP command replies and parse frame trees once

CdpConnection.send is typed by method name. A command registered in
src/browser/protocol/CdpCommands.ts has its parameters typed from the
protocol table Playwright ships and its reply parsed once by its own result
schema; a mismatch rejects that command with CdpMalformedReply
(protocol_error, command, JSON pointer) without poisoning the connection.
Playwright storage sessions admit replies through the same table.

Page.getFrameTree and Page.getResourceTree are the first registered
commands. Their one parser keeps per-frame facts tolerant (malformed child
entries remain explicit omissions) and replaces the per-site readers:
observeMainFrameUrl, mainFrameUrl, walkFrameTrees, frameTreeResources,
runtimeFrameTreeSchema and the scenario storage frame schema.

A reply without a frame tree used to be retried for two seconds and
reported as target_not_allowed; it is now one protocol_error.

A guard test counts literal CDP command names without a result schema per
source file; the baseline can only shrink.

* fix(browser): consume parsed CDP facts across boundaries

* refactor(browser): register target, storage and acknowledgement CDP replies

Register result schemas for Target.attachToTarget, Target.getTargetInfo,
Storage.getStorageKey, Page.addScriptToEvaluateOnNewDocument,
Debugger.setBreakpointByUrl, Debugger.evaluateOnCallFrame and fourteen
commands whose reply REA reads only as success. Their callers use the
parsed reply; the per-site readers are removed (attachedSessionId and the
scenario storage and service-worker zod schemas, which threw raw ZodError).

Playwright's Target.getTargetInfo in scenario attach now goes through the
same admission. The untyped-command baseline drops from 96 to 48.
2026-11-14 23:40:44 +00:00
morluto f3b697da5a refactor(cli): derive contract-backed command options from the tool contract (#10571)
* refactor(cli): derive contract-backed command options from the tool contract

Each contract-backed CLI command restated its contract's input fields as
hand-written incur options and mapped them back to snake_case input with
conditional spreads. Nothing checked that the two schemas agreed.

Add registerContractCommand: a per-command projection names only what the
CLI spells differently (positionals, caller-relative path fields, option
renames, CLI help wording, omitted optional fields with a reason). Option
schemas, decimal argv tokens and the contract's cross-field rules are
derived from the contract input schema, and parsed options map back to the
contract input mechanically.

Migrate inspect-sqlite-database and the thirteen flat binary-diagnostics
inspectors. Their --schema output is unchanged apart from property order,
and help lists options in contract order. Delete the SQLite superRefine that
mirrored the contract and the per-command spreads.

Add a parity test: every projected command exposes each contract field or
declares its omission, and each field admits exactly what the contract
admits for empty, NUL, relative-path, bound and numeric-spelling probes.

* refactor(cli): refuse unprojected contract input forms at registration

Address review findings on the contract projection:

- Bind inspect-sqlite-database to its contract by name instead of catalog
  position.
- Accept only field forms argv can carry (string, number, boolean, enum,
  and arrays of strings or enums) instead of rejecting a short list, so
  arrays of objects, tuples and other forms fail at registration.
- Refuse root input keywords other than the projected object constraints
  and presentation annotations, so a contract rule such as `not` cannot
  disappear from --schema.

* refactor(cli): describe contract commands independently of the CLI framework

Split the contract projection into a framework-neutral description and a
thin Incur adapter, so a later REA-owned CLI layer (#10583) can render the
same description.

- contractCliDescription.ts derives each positional and option from the
  contract and projection: key and short flag, help, argv admission
  schema, boolean-flag/repeatable/decimal/caller-path facts, object
  constraints renamed to CLI keys, the optional argv-time cross-field
  check, and the mapping back to contract input.
- contractCommand.ts only renders that description as Incur args and
  options and runs the handler.

Cross-field rules now refuse at argv parsing only when a projection asks
(inspect-sqlite-database does, keeping its behavior); otherwise the
service's contract parse refuses them as before. Exact-optional fields are
projected as optional because argv cannot carry an explicit undefined and
Incur's help reads flag and choice types only through optional.

The parity guard reads the descriptions, and also checks that boolean
fields parse as bare flags and that no projected field stays
exact-optional.
2026-11-15 04:30:18 +08:00
morluto 29fb608559 refactor(rust): report cargo-auditable section failures through ParseFailure (#10652)
* refactor(rust): report cargo-auditable section failures through ParseFailure

RustAuditableFormatFailure restated the malformed/unsupported algebra and
the provider translated it by hand; container BinaryFormatFailures were
re-wrapped and lost their kind. The reader now throws ParseFailureError
(format rust-auditable), container failures propagate unchanged, and the
provider maps both through parseFailureAnalysisError. A counted guard
keeps new per-format failure classes from returning.

* test(rust): pin the container's truncated failure facts through the Rust reader
2026-11-14 15:28:33 -05:00
morluto 3e0dc29041 fix(browser): type CDP command replies and parse frame trees once (#10604)
* fix(browser): type CDP command replies and parse frame trees once

CdpConnection.send is typed by method name. A command registered in
src/browser/protocol/CdpCommands.ts has its parameters typed from the
protocol table Playwright ships and its reply parsed once by its own result
schema; a mismatch rejects that command with CdpMalformedReply
(protocol_error, command, JSON pointer) without poisoning the connection.
Playwright storage sessions admit replies through the same table.

Page.getFrameTree and Page.getResourceTree are the first registered
commands. Their one parser keeps per-frame facts tolerant (malformed child
entries remain explicit omissions) and replaces the per-site readers:
observeMainFrameUrl, mainFrameUrl, walkFrameTrees, frameTreeResources,
runtimeFrameTreeSchema and the scenario storage frame schema.

A reply without a frame tree used to be retried for two seconds and
reported as target_not_allowed; it is now one protocol_error.

A guard test counts literal CDP command names without a result schema per
source file; the baseline can only shrink.

* fix(browser): consume parsed CDP facts across boundaries
2026-11-14 15:21:00 -05:00
morluto ef1b92bf1e test(mcp): check advertised schemas against a portable dialect in every profile (#10567)
* test(mcp): check advertised schemas against a portable dialect in every profile

* fix(mcp): validate advertised dialect by selected profile

* fix(mcp): refuse zero-padded repeat bounds and record host-specific path patterns
2026-11-14 15:20:31 -05:00
morluto 85da0bd4ee refactor(errors): require a reason for every analysis cancellation (#10566)
* refactor(errors): require a reason for every analysis cancellation

Add cancelledBy, the one constructor for AnalysisCancelledError. Its
reason argument is required: an aborted signal, an earlier cancellation,
a reason carried from an inner failure, or an OwnerCancellation when REA
closed the work's owner itself.

Closed adb, apktool, firmware, sqlite, gdb, web-bundle analyzer and
binary-session record owners now report OwnerCancellation.ownerClosed
instead of an absent reason. Firmware's predecessor wait returns its
cancellation as a Result, removing an unreachable reason-less fallback.

An architecture guard rejects new direct constructions, with a counted
per-file baseline that can only shrink.

* refactor(errors): share one aborted-signal predicate with cancelledBy

* refactor(process): return a departing caller's reason from a shared startup wait

* refactor(providers): build decompiler-provider cancellations with a required reason (#10587)

Migrate every AnalysisCancelledError construction under src/ghidra,
src/ida, src/cutter, src/jeb and src/kuna to cancelledBy and lower the
guard baseline from 671 to 572. Closed Kuna target commands report
OwnerCancellation.ownerClosed instead of an absent reason, and Kuna and
JEB close abort their lifetimes with that typed reason.

* fix(errors): read the reason of any signal-shaped cancellation source

* test(ci): cover the counted-baseline comparison behind the architecture guard
2026-11-14 15:20:03 -05:00
morluto 2f4c588584 fix(artifacts): require each reader traversal to declare its coverage (#10572)
* fix(artifacts): require each reader traversal to declare its coverage

* docs(artifacts): state that silent traversals report unknown coverage
2026-11-15 04:07:21 +08:00
morluto dfad81a48b test(cli): publish polled readiness files only when complete (#10563)
The doctor cancellation fixture wrote its readiness JSON with
writeFileSync, which truncates and then writes. The test polls only for
the file's existence, so a read between the two steps parsed an empty
file and failed with "Unexpected end of JSON input" (main run
43604752864, PR run 43606296871).

Write to a pending path and rename it into place, as ghidraJavaDoctor and
darwinProcessRunTokenReader fixtures already do. Apply the same fix to the
two sibling fixtures that poll for a PID file's existence and then parse
it: jadxConfiguration and runnerCancellation, where an empty read becomes
PID 0.
2026-11-14 14:51:30 -05:00
morluto e68e548a3d fix(cli): validate plist and dylib-root options with their contract fields (#10557)
* fix(cli): validate plist and dylib-root options with their contract fields

inspect-plist --relative-path and trace-dylib-resolution --root were
declared as bare strings on the CLI. --schema under-advertised them, and an
empty or NUL value reached the operation contract, whose refusal named the
contract field (path, roots) instead of the CLI option.

Declare both options with the contract's own field schemas
(localPathStringSchema; dylibResolutionInputSchema.shape.roots), so the CLI
refuses them first and names --relative-path or --root.

Fixes #9764
Fixes #9823

* fix(mcp): observe SDK initiated cleanup failures
2026-11-14 14:50:59 -05:00
morluto 01192ab737 test(hopper): assert retained cleanup without optional diagnostics (#10636) 2026-11-14 14:40:59 -05:00
morluto a09d3bed94 refactor(filesystem): hash admitted target descriptors with the shared stable hasher (#10573)
BinaryTargetResolver kept a private copy of StableFileHash's descriptor read
loop because it must hash the same descriptor it classified, admitted with
symlinks rejected, while hashStableFile opens its own descriptor and follows
symlinks. The loop is now hashStableRegularFileDescriptor, which takes the
admitted descriptor and the caller's symlink setting; readStableFile and the
resolver both use it. The resolver keeps symlinks: reject and maps a change
to its existing BinaryTargetError and cancellation to AnalysisCancelledError.
2026-11-14 14:37:30 -05:00
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