Commit Graph
257 Commits
Author SHA1 Message Date
morluto 80de3145e4 fix(mcp): align advertised contracts and retain workflow evidence
Use one named input-schema projection for clients and catalog identity, preserve dialect declarations, and bound compact schema depth. Keep canonical SDK output validation when output advertisements are disabled. Release request-owned state on cancellation and carry upstream limitations through composed workflows. Preserve doctor full-output envelopes and validate navigation facts at their owner.

Reviewed fixes: #2088, #2108, #2513, #2684, #2693, #2695, #2836, #2864, #2868, #2877, #2933, #2998, #3002, #3015.

Validation: focused schema, SDK output-validation, context, and workflow tests passed; no schema dialect or canonical output validation was relaxed.
2026-10-14 08:32:00 +08:00
morluto 55dd21a5e2 fix(native): retain partial format facts and explicit coverage
Preserve XML and Interface Builder identity at their parsing boundary, retain usable Objective-C slots with precise coverage, and keep native trace failures distinct from absence. Add caller-selected Interface Builder summaries backed by complete retained Evidence, and preserve comparison limitations.

Reviewed fixes: #1969, #2088, #2108, #2513, #2639, #2684, #2731, #2759, #2875, #2888, #2889, #2970, #2971, #3002.

Validation: relevant native/domain focused lane passed 142 tests; earlier Interface Builder/MCP checks passed 24 tests. Real native UI and Ghidra producer coverage was not repeated.
2026-10-14 08:29:16 +08:00
4aa51bfe19 fix(reverse): reconcile cleanup ownership and mutation diagnostics (#2799)
* feat(process): add owned debugger shutdown lifecycle

* feat(reverse): add local inspection commands

* feat(gdb): add persistent debugger integration

* feat(cutter): add Cutter bridge integration

* test(reverse): enforce complete integration coverage

* fix(process): preserve debugger shutdown ownership

* fix(reverse): retain evidence across interrupted commands

* fix(gdb): honor captured provider environment

* test(process): cover debugger shutdown retries

* fix(reverse): retain evidence for interrupted providers

* test(process): cover debugger shutdown retries

* fix(reverse): retain evidence for interrupted providers

* fix(server): snapshot provider environment at creation

* fix(reverse): close review gaps with complete coverage

* fix(reverse): address inspection review findings

* fix(gdb): bound sessions and retain cleanup ownership

* fix(ci): require reverse-tools quality lane

* fix(process): unref inherited debugger output pipes

* fix(reverse): address remaining PR 1960 findings

* fix(gdb): address remaining PR 1961 findings

* fix(reverse): account for unrestricted provider execution

* fix(process): retain debugger ownership until safe shutdown

* fix(process): preserve replacement debugger sessions

* fix(reverse): preserve admission and output provenance

* fix(process): retain exited debugger until output settles

* fix(mcp): bound provider admission and debugger cleanup

* fix(reverse): preserve failure provenance and classify E2BIG

* fix(gdb): preserve startup cleanup and detach safety

* fix(process): retain debugger ownership after detach failure

* fix(reverse): preserve mutation and failure provenance

* fix(gdb): address debugger review findings

* fix(reverse): rebind sessions after external mutation

* fix(process): cap debugger output after exit

* fix(gdb): protect one-shot detach verification

* feat(debugger): add reverse tool coverage gate

* test(debugger): cover integrated failure paths

* fix(gdb): bound and preserve session observations

* fix(gdb): address review regressions

* style: format merged integration files

* fix(reverse): preserve session and output evidence

* refactor(gdb): share repeated test and partial result setup

* fix(gdb): invalidate TTY proof for Python aliases

* fix(reverse): retain failure output byte counts

* test(process): synchronize late debugger output

* fix(gdb): invalidate TTY proof for wrapped commands

* fix(gdb): recognize wit command abbreviation

* test(reverse): wait for cancelled descendant readiness

* test(reverse): bound descendant cancellation cleanup

* style(reverse): format integration tests and adapters

* style: format reverse engineering integration files

* test(reverse): remove duplicate environment harness

* test(gdb): share session startup assertions

* fix(gdb): invalidate output proof for command abbreviations

* test(reverse): share composition edge case scenarios

* fix(ci): recognize verification and mutation tool entries

* test(rizin): cover successful fake inferior detach

* test(cli): align full output failure envelope

* test(cli): isolate reverse command lifecycle service

* test(process): share debugger output fixture setup

* fix(binary): preserve high-bit Windows signature bytes

* style(binary): format Windows signature parser

* test(mcp): preserve call coverage in unchanged comparison

* fix(ci): include reverse tools Vitest configs in lint cache

* fix(mcp): preserve target content on delivery errors

* ci: align duplication ceiling with expanded suite

* test(reverse): allow signal admission mutants

* fix(reverse): bound retained cleanup failures to process owners

* fix(test): replace drifting mutation ranges with owned selectors

* fix(reverse): admit persistent commands and retain cleanup ownership

* fix(cutter): recover timed-out commands from exact receipts

* fix(cutter): reject unsupported bridge request kinds

* fix(ci): repair client format and shared verification fixtures

* fix(native): preserve debugger cleanup ownership and bridge authentication

* test(native): retain diagnostics without perfect coverage requirements

* chore(licenses): refresh locked dependency inventory and notices

* fix(test): exclude transient command locks from mutation sandboxes

* fix(gdb): admit only platforms with safe detach verification

* fix(cutter): retain bounded completion receipts until acknowledgement

* fix(cutter): acknowledge commands rejected before UI dispatch

* test(reverse): fail cancellation checks before fixture teardown

* test(gdb): clean up the retained broken-stdin fixture owner

* docs(test): clarify focused provider verification scope

* fix(rizin): retain close cleanup failures

* fix(gdb): wait for inferior stop and bound MI buffering

* fix(cutter): retain failed receipt acknowledgements

* fix(rizin): return retained session identity on rebind failure

* fix(gdb): preserve startup cancellation and lossy status

* fix(rizin): retain launch provenance and assemble frames once

* fix(cutter): recover receipts across callers and bound discovery

* docs: describe debugger evidence and bridge recovery

* fix(process): keep cleanup incomplete while writers remain

Stopping a debugger no longer reports success when inherited output
streams stay open, so BinarySession cannot reopen a binary a child is
still changing. Concurrent Cutter cleanup retries share one receipt
acknowledgement instead of treating a consumed receipt as failure.

* fix(debuggers): recover cleanup with captured process identities

* fix(analysis): retire sessions after unrestricted commands

* fix(cli): preserve completed evidence after cleanup recovery

* fix(cutter): bound frame collection and coalesce cleanup

* fix(windows): resolve selected provider paths absolutely

* fix(gdb): report decoding loss in failed startup evidence

* fix(rizin): scope decoding loss to collected command frames

* test(mcp): cover snapshot retirement in reverse tools CI

---------

Co-authored-by: Daniel Gonçalves Araujo <47118053+dandgabr@users.noreply.github.com>
Co-authored-by: REA Maintainers <noreply@github.com>
Co-authored-by: OpenAI Codex <codex@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-14 04:47:34 +08:00
4481f86188 fix(frida): drain admitted operations and honor queued cancellation (#2305)
* fix(frida): drain admitted operations and honor queued cancellation

* fix(frida): settle cancelled loads before queued resume

* test(frida): share lifecycle fixtures without duplicating assertions

* fix(frida): preserve operation admission before session close

* test(apple): bound cold archive fixture compilation

* fix(frida): retain cancelled script creation evidence

* test(release): scope preflight schema to selected jobs

* fix(process): report no remaining time after a provider deadline fires

Node timers can fire while performance.now() is still a fraction of a
millisecond short of the monotonic deadline. ProviderStartupDeadline then
reported interruption "timeout" and an aborted signal while remainingMs()
returned ceil(0.x) = 1, so polling loops guarded by remainingMs() > 0
(Hopper and Ghidra startup) could run past an elapsed deadline, and the
real-timer test "aborts a bounded wait when its real monotonic deadline
expires" failed intermittently in CI (expected 1 to be 0).

Once the deadline's own timer has classified a timeout, report zero
remaining time. A deterministic regression test fires the timer with the
monotonic clock 0.4 ms short of the deadline.

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

* fix(comparison): recheck historical calls-only changes (#2223)

* fix(comparison): preserve incomplete function call evidence

Keep missing, unknown, partial and unresolved call relationships unknown in function comparisons and reconstruction claims. Aggregate IDA caller and callee coverage without overwriting uncertainty.

Validate with 144 focused tests, typecheck/lint, docs checks and test discovery. Real providers were not verified; the full headless IDA session suite requires unavailable Windows native controls.

* fix(comparison): recheck historical calls-only changes

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
(cherry picked from commit 688defca0f)

* fix(ci): isolate Linux Hopper process fixture inventory

(cherry picked from commit 8cac51e121)

* fix(android): make DEX descriptor pattern portable

(cherry picked from commit 1335bcddc5)

* fix: repair the static-check failures on the default branch (#2895)

* fix: repair the static-check failures on the default branch

The default branch fails its own required `Static checks` job three ways, so
every pull request reports that job as failed regardless of its own change.

- `npm run format:check` reports `src/domain/functionComparison.test.ts` and
  `src/ida/IdaOperationRunner.ts`.
- `npm run lint` reports a duplicate `import { join } from "node:path"` in
  `tests/boundary/mcp/ghidraInventoryMcp.test.ts` (lines 4 and 17).
- `npm run typecheck` reports `format: "devin"` missing from the client format
  union in `src/application/SupportedClients.ts`, and an unchecked index in
  `tests/boundary/cli/clientProfileLifecycle.test.ts`, whose pair array is
  inferred as `string[][]`.

Apply the pinned formatter, drop the duplicate import, list the `"devin"` format
that its own definition already uses, and mark the pair array `as const`.

Validation: `npm run check:fast` and `npm run format:check` pass.

* fix(setup): keep Devin on the JSON configuration dialect

---------

Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
(cherry picked from commit df3d96da80)

---------

Co-authored-by: morluto <morluto@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: Lucien <164857476+dakjdakd@users.noreply.github.com>
Co-authored-by: 吴佳浩Alben <35291372+XiaoBinGan@users.noreply.github.com>
Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
2026-10-14 02:56:00 +08:00
0e6eca4085 feat(native): read embedded cargo-auditable Rust dependency lists (#2456)
* feat(native): read embedded cargo-auditable Rust dependency lists

* fix(native): trim PE section padding and compute dependency cycles iteratively

* fix(native): ignore SHT_NOBITS sections and validate dependency edges linearly

* fix(native): bound compiler path scanning and retained hashes

* fix(rust): pass package arrays as named parameterized test cases

* fix(rust): admit graph expansion and preserve resource units

* fix(rust): reject malformed packages, false cycles, and hidden compiler paths

Fail the first malformed cargo-auditable package before Zod collects an
issue per field. Require cyclic dependency indices to match the cycles in
package dependencies. Keep read-only ELF ranges when a section name does
not fit the bounded name window, so a rustc path in that range is still
reported.

* fix(ci): repair integrated checks and Hopper test baseline

* fix(go): verify Mach-O sections against segments

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-14 02:50:30 +08:00
Thang LuuandThang Luu 911894d758 feat(wasm): compare retained core-module interfaces (#2464)
Squash merge of https://github.com/morluto/rea/pull/2464.

Co-authored-by: Thang Luu <76550342+thangldw@users.noreply.github.com>
2026-10-13 23:49:04 +08:00
Shubham AhujaandClaude Opus 5.5 3e7c630223 fix(mcp): count the error flag in error result budgets (#2848)
Error results reach the wire as text plus `isError: true`, but the
text-only envelope omitted the flag. An error up to 15 bytes above the
result budget passed both the delivery and transport checks and was sent
as the original diagnostic instead of taking the oversized-error recovery
path.

Rename the error representation to "error-text" and size its envelope
with the flag, so ToolResultDelivery and the error transport share the
complete delivered shape. Successful structured results are unchanged.

Fixes #2557

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 23:06:55 +08:00
9680da76c8 perf(evidence): reuse sealed bundle reads in compare and export (#2715)
* perf(evidence): reuse sealed bundle reads in compare and export

`rea compare`, the compare_bundles MCP tool and `rea evidence-export`
read bundles through the mutable reader, so each consumer
re-authenticated every record again: compareBundles parsed both bundles
a second time and bundleDigest's serializeEvidenceBundle a third time;
export's writer parsed the source once more before serializing.

These consumers only read the bundle, so read it through the existing
sealed reader (readImmutableEvidenceBundle). Later parses hit the
immutable bundle cache. Ordinary mutable reads, kept deliberately by
#1721, are unchanged. Output is byte-identical.

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

* fix(process): report no remaining time after a provider deadline fires

Node timers can fire while performance.now() is still a fraction of a
millisecond short of the monotonic deadline. ProviderStartupDeadline then
reported interruption "timeout" and an aborted signal while remainingMs()
returned ceil(0.x) = 1, so polling loops guarded by remainingMs() > 0
(Hopper and Ghidra startup) could run past an elapsed deadline, and the
real-timer test "aborts a bounded wait when its real monotonic deadline
expires" failed intermittently in CI (expected 1 to be 0).

Once the deadline's own timer has classified a timeout, report zero
remaining time. A deterministic regression test fires the timer with the
monotonic clock 0.4 ms short of the deadline.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:50:25 +08:00
morluto b955b825fc fix(artifacts): retain read cleanup ownership through CLI and MCP shutdown
Keep failed stable-read handles and WABT runtime roots under retryable resource scopes. Preserve cancellation causes and primary errors, close the same service instances bound to MCP tools, and consolidate CLI operation/cleanup projection.

Validation: fast typecheck and lint, cached runtime build, docs checks, SDK schema validation, focused service and real-file cleanup tests, CLI cleanup regressions, and MCP lifecycle/shutdown workflows. Provider process fixtures simulate engine output; real WABT and Linux EVM execution are not established by this pass.
2026-10-13 16:08:41 +08:00
Kaoru0822andClaude Opus 5.5 bf34d0d2fc perf(native): add opt-in Mach-O summary delivery and retained pages (#2634)
* perf(native): add opt-in Mach-O summary delivery and retained pages

inspect_macho returns every import and export inline. For VS Code's
Electron Framework one MCP call carries 2.5 MB of text (about 828k o200k
tokens), and the same again as structuredContent; the MCP response
budget admits it. Agents asking for slice identity, UUID or dependency
counts paid that cost on every first call.

Add the established opt-in detail selection: omitted or complete keeps
the existing complete result and Evidence identity, while summary
retains the complete Evidence and returns slice identity with
per-collection returned/total/exhaustive counts (956 tokens).
inspect_analysis_view kind macho pages the original rows of any
collection or the command provenance, repeating the producer's own
total and exhaustive flag so page exhaustion is never read as absence.

Delivery detail never reaches the native tools or the source Evidence
ID: registerEvidenceTools gains a parametersForEvidence hook, so the
summary's parent is the same Evidence as a complete call.

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

* fix(mcp): refuse unretainable summary delivery before analysis

A server without Evidence retention (a fixed analysis source) ran the
complete inspect_macho or inspect_artifact analysis for detail summary
and only then refused it in summarizeRetainedAnalysis, paying the very
cost summary delivery exists to avoid. registerEvidenceTools gains a
preflight hook; both registrations check retention there, as the WASM,
EVM, managed, pcap and capture handlers already do before dispatch.

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

* fix(native): keep whole rows in Mach-O architecture and segment pages

The page item union listed plain-object row arrays, and zod returns the
first union member that parses while dropping unknown keys. Entrypoint
rows declare only file_offset, so every architecture and segment row
(which also carry a numeric file_offset) matched it and lost its name,
CPU fields, permissions and sections. Rows now use exact key sets, and
imports/exports share one member. The MCP test pages every facet of a
real /bin/ls and compares it with the unparsed complete rows.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 00:13:12 -07:00
Olorin 4276aaf18b feat(signals): discover installed decoders and option help (#2487)
* feat(signals): discover installed decoders and selected option help

* fix(signals): bound retained discovery data and preserve resource failures

* fix(signals): complete CLI help and portable decoder patterns

* test(signals): verify case-insensitive decoder help queries

* fix(signals): retain discovery operation across cleanup retries
2026-10-13 15:58:19 +09:00
OlorinandN0zoM1z0 9c34c091b3 feat(captures): discover installed protocol and field definitions (#2496)
* feat(captures): discover installed protocol and field definitions

* test(captures): isolate the direct glossary oracle profile

* test(captures): accept padded kernel limit reports

* fix(captures): detach every retained glossary column

* fix(captures): describe every field discovery CLI option

* fix(captures): retain discovery operation across cleanup retries

---------

Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-13 15:55:25 +09:00
morluto 55e21a2eec Merge remote-tracking branch 'origin/main' 2026-10-13 14:51:59 +08:00
Rohit Ghumare 12303812a8 fix(evidence): admit bundle imports across session transitions (#2303) 2026-10-13 14:45:03 +08:00
morluto 26bffb94bf perf(evidence): reuse authenticated comparisons through aggregation 2026-10-13 14:39:49 +08:00
Quentin LimoandN0zoM1z0 9581e067ad feat(pcap): add bounded capture summaries through CLI and MCP
Summarize saved Wireshark4.x captures with enforced native resource limits, serialized admission, stable snapshot verification and retained fact/text pages. Preserve complete inventories within resource budgets and source uncertainty; report cleanup failure with partial Evidence and retained ownership.

Verified six recorded corpora /13026 packets with independent Scapy/Python oracles, real CLI/MCP/schema parity,60 SNI names,132 DNS addresses and1000 URIs. Real TShark CI now exercises summary/paging. Actual Windows/Bun Wireshark remains unverified; macOS capture requires a separate enforceable-bound decision.

Co-authored-by: 3QL <85309073+3QL@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-13 04:53:03 +00:00
Ysopwnableandfactory-droid[bot] 23de4f77c7 perf(flutter): add opt-in retained AOT summary and string pages
Add explicit MCP Dart AOT summary delivery and exact retained string-pool pages while preserving complete defaults, CLI behavior, ABI selection, original Evidence identity, partial coverage and lower bounds.

Real LocalSend SDK replies shrink 92.05% with approximately unchanged SDK time. Two actual Codex pairs preserve all selected facts and reduce total input 48.75% / 42.38%, uncached input 33.63% / 42.52%, and task time 23.95% / 30.30%; all client errors/repeated calls remain counted. Preserve old portable Evidence and the real CLI complete result after rebasing onto SAZ/qlog main. Curated results keep measured and integration runtime pins separate; raw artifacts stay outside Git.

Refs #2016.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-13 11:39:30 +08:00
LuisandN0zoM1z0 bb154d1067 feat(browser): inspect retained aioquic qlog JSON captures
Inspect bounded offline aioquic1.5.0 JSON qlog0.3 and page retained event/transport facts with explicit trace and stream selectors. Preserve producer coordinates, exact numeric lexemes, global pre-selection fact scope and endpoint declaration uncertainty.

Verified four real HTTP/3 recordings with an independent interval oracle, public CLI/MCP/schema parity, auth exclusions, source-deletion views and actual decoder heap exhaustion. Unverified producer platforms and qlog-specific lifecycle induction remain documented.

Co-authored-by: LuisTaffelli <86675342+LuisTaffelli@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-13 03:24:05 +00:00
a2d8b94dd5 feat(fiddler): inspect native SAZ captures
Inspect bounded recorded raw HTTP/XML SAZ archives and page retained capture Evidence. Preserve exact stored bytes and provenance, validate ZIP/XML integrity, and require an enforceable decoder memory bound.

Verified 356 real recorded sessions against independent byte and metadata oracles, public CLI/MCP parity, retained pages, and related interface checks. Current Fiddler Everywhere GUI and non-Linux producer workflows remain unverified.

Co-authored-by: zahhak <1792039+zahhak@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-13 02:51:14 +00:00
Ysopwnableandfactory-droid[bot] f254f5ac2b feat(android): add opt-in package summaries and retained manifest views
Add explicit package summary delivery and exact retained manifest pages while preserving complete MCP defaults, one-shot CLI output, provider requests, source identity and session lifetime. Return distinct linked Evidence and preserve partial/null facts; reject unavailable retention before engine work.

Validation: 27 relevant SDK/domain/Android boundary checks, focused test-only correction rerun, full supported compiler/lint and docs checks, real NewPipe SDK pairs, authentic old Evidence continuation, four actual Codex trials with failures/regressions retained, and all 39 exact-head CI checks. Package replies shrink 119,527 to 8,659 bytes; no model-token or time gain is established.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-13 10:21:53 +08:00
morluto 9a18251426 feat(mcp): add opt-in paging for retained unknown heads
Keep complete default delivery and exact filters. Select stable ID pages at the ledger owner before cloning, return filtered totals and continuation offsets, and preserve detached records through the shared session port.

Validate public MCP paging, safe-integer edges, snapshot replay and converted JSON Schemas. Document the bounded Flameox workflow comparison and its token/CPU/latency measurement limits; no real model performance claim.
2026-10-13 08:08:24 +08:00
Ysopwnableandfactory-droid[bot] 82cfcee19f feat(managed): add retained metadata overview and pages (#2413)
Add caller-selected managed metadata summaries and original collection pages while preserving complete CLI/MCP defaults and previous-runtime Evidence. Real SDK replies shrink substantially; actual Codex token/latency results remain mixed and are documented without a token-saving claim.

Validated focused SDK/domain tests, full static/docs checks, real two-assembly repeated workflows and portable old Evidence, real SQLite WASM, and all exact-head CI checks. Raw experimental artifacts remain private.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-13 07:41:20 +08:00
morluto 8fc2043eb8 fix(mcp): preserve target provenance on retained partial errors 2026-10-13 05:25:15 +08:00
Lluís Ariño 85e124253a feat(server): frame analysis-target content as untrusted data (#1908)
* feat(server): frame analysis-target content as untrusted data

Strings, decompiled code, page text, scripts, captures and logs returned
by REA originate from the analysed target, which can embed text aimed at
the agent. Nothing marked that content, so a prompt injection inside a
binary or page could steer the agent toward tools that run code.

- Server instructions now state that target-derived tool output is data,
  never instructions, and that any request in it to run, install,
  download or send something is a prompt-injection attempt to report.
- Tool contracts declare returnsTargetContent. It is on by default; only
  seven tools whose results hold REA session state or caller-supplied
  values (binary_session, close_binary, export_evidence_bundle,
  record_unknown, update_unknown, inspect_adb_client,
  inspect_apktool_client) are audited exceptions, so new tools start
  marked.
- Successful results of marked tools carry
  _meta.provenance = { untrusted_content: true, source: "analysis_target" }.
  content and structuredContent are unchanged, and the response budget
  accounts for the fixed marker bytes.

Tests cover the encoding and budget accounting, the audited exception
list against the contract catalog, and an in-memory MCP client that sees
the instructions and the marker on a marked tool but not on
binary_session.

* fix(server): mark failed target-content results as untrusted too

The untrusted provenance marker was attached only on the success branch
of ToolResultDelivery, but failures can carry target-derived text as
well: error messages, captured output, and partial observations such as
the terminal frames a failed capture_process_scenario retains in
partial_observation. A host gating later process or device actions on the
marker would have treated an adversarial error payload as trusted.

Every error path in src/server now carries the failing tool's provenance:
- toErrorToolResult and toRecordedPartialErrorToolResult take the tool's
  target-content flag explicitly, so each caller is audited by the type
  checker; toCallToolResult, toEvidenceToolResult (recording failure), the
  response-budget error that replaces an oversized success, and the
  Electron partial-evidence path pass contract.returnsTargetContent.
- Admission failures in runAdmittedToolOperation resolve the flag from the
  tool name through the new toolReturnsTargetContent, the same predicate
  the contract metadata uses; unknown names stay marked.
- The transport's oversized-error replacement keeps the original's marker
  and counts it in its budget check, matching the projected error.
- Errors the MCP SDK builds itself (input validation, thrown handlers) are
  marked in the transport for target-content tools only.

Error encoding accounts for the marker bytes exactly as success encoding
does. docs/mcp-contracts.md now states that error results carry the
marker. Tests cover marked and unmarked error results, the
capture_process_scenario partial-observation errors in-process and over
the SDK transport, the recorded partial-evidence path, the budget
replacement, the oversized-error replacement, and SDK validation errors
for a marked and a content-free tool.

* fix(contracts): mark session status, close and client probes as target content

The content-free exception set was audited against successful results
only. Now that failures carry the marker too, every exception was
re-audited against its error paths with one question: can the result
include text produced by an external process, provider or device, or
stored content REA did not author?

Removed from TARGET_CONTENT_FREE_TOOLS:
- close_binary: a failed provider cleanup (GhidraClient cleanup error via
  createGhidraDiagnostics) projects the launcher's captured stdout and
  stderr, which can contain target-derived log text.
- binary_session: capability status reports runtime unavailability as the
  provider error message (ProviderAdapterError and similar), and the
  provider candidate and Android availability diagnostics include probe
  output such as the apktool stderr excerpt.
- inspect_adb_client: the success result carries the version and
  installed path parsed from `adb version` stdout, and a failed probe
  keeps a stderr_excerpt.
- inspect_apktool_client: the success result carries the first line of
  the launcher's `--version` output, and a failed probe keeps a
  stderr_excerpt.
- update_unknown: the new revision carries forward the stored question
  and domain, which an imported evidence bundle can supply; list_unknowns
  and get_evidence_bundle already return that data marked.

The set now holds only export_evidence_bundle (path, byte and record
counts; failures are filesystem, cancellation, or a fixed integrity
message) and record_unknown (the caller's input plus REA-computed ids
and digests; registry errors project only a reason code).

The conformance test pins the reduced set and asserts each removed tool
is marked. Tests that used binary_session as the unmarked example now use
record_unknown. docs/mcp-contracts.md lists the remaining exceptions and
why the removed tools stay marked.

* fix(contracts): include target-content policy in the catalog identity

createToolCatalog() and CATALOG_IDENTITY.tools projected every
client-visible contract field except returnsTargetContent. Because the
untrusted-content framing left schemas, effects, prompts, CLI names and
the package version unchanged, a same-version MCP process started before
the update digested equal to the new server and binary_session reported
it aligned although it never emits _meta.provenance.

Project the flag as returns_target_content in both the digested tool
catalog and CATALOG_IDENTITY.tools, and export createCatalogDigests so a
boundary test proves that toggling the flag on one tool changes the
tools and combined digests.
2026-10-13 06:06:02 +09:00
YsopwnableandOlorinm 91b8f587cd feat(signals): decode recordings with bounded sigrok output (#2339)
Decode caller-selected protocols from existing recordings through shared
CLI/MCP Evidence. Page literal output lines after complete decoding;
preserve explicit full output, source identity and failed cleanup ownership.

Verified real sigrok-cli 0.7.2 workflows, published UART/SPI/I2C recordings,
independent UART values, selector limits, SDK schemas and cleanup regressions.

Co-authored-by: Olorinm <59321404+Olorinm@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-12 20:59:02 +00:00
morluto 049132ab43 fix(evidence): preserve call coverage in function comparisons
Treat missing, partial, unknown, and unresolved call coverage as insufficient for call-set equality. Combine IDA caller/callee coverage without losing either explanation and recheck source coverage when verifying historical comparisons.

Scope generated function-comparison unknowns with optional typed comparison/dimension facts, preserving legacy IDs and revision digests when absent. Keep unrelated dimensions conclusive, explicit dependencies applicable, and ambiguous function identity unknown. A confirmed change for matched functions remains a failure even if calls are incomplete.

Validation: function/reconstruction/residual-unknown and bundle tests, recorded IDA protocol regression, public MCP comparison/verification, and advertised SDK JSON Schema checks. Real IDA provider execution was not verified.

Fixes #2222
2026-10-13 04:12:34 +08:00
YsopwnableandOlorinm f611d8ce72 feat(captures): inspect recorded packets with bounded TShark delivery (#2318)
Inspect selected fields in existing captures through shared CLI/MCP Evidence.
Page matching frames without changing dissection or two-pass read coverage;
retain failed descriptor/process cleanup ownership and reject excess admission.

Verified with real TShark 4.0.17 and 4.2.2, public Wireshark recordings,
owned HTTP application traffic, real CLI/MCP workflows and schema checks.

Co-authored-by: Olorinm <59321404+Olorinm@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-12 19:35:35 +00:00
Ysopwnableandfactory-droid[bot] f76163c246 feat(evm): add retained interface summary delivery (#2308)
Add opt-in EVM MCP summary delivery and retained/portable function and text views. Keep existing complete defaults, provider arguments and original full Evidence identities and records usable. Require retention before selected analysis; preserve inferred candidates, nulls, diagnostics, provenance and explicit unknowns.

Verify old schemas, historical Evidence migration, 64 focused feature checks, 30 affected MCP checks after latest-main rebase, 59 real EVM CLI/MCP cases and six shared-domain artifact workflows. Repeated SDK delivery is smaller; all real model trials and mixed token/time outcomes, limitation failures and resource qualification gaps remain documented without a uniform performance claim.

Refs #2016

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-13 03:09:32 +08:00
YsopwnableandY0UW1SH aeee5074d1 feat(sqlite): inspect offline snapshots with selective evidence (#2271)
Add offline SQLite database/WAL inspection through the shared CLI/MCP.

Use compact inventory, selected-table schema, exact ordered columns and
bounded row samples while preserving source identity and lossless values.
Retain completed Evidence through late cancellation and private-root cleanup
failures, bound concurrent inspections, and recheck journal validity after
acquisition. Reuse prepared CI runtime artifacts across supported Node lines.

Co-authored-by: Y0UW1SH <29498139+Y0UW1SH@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-12 18:33:23 +00:00
Yijie Luandmorluto 11fe5a13f8 fix(native): retain failed pwntools process and runtime cleanup (#1708)
* fix(native): retain failed pwntools process and runtime cleanup

Keep failed worker/debugger cleanup owners and their private files until
verified process shutdown and successful directory removal. Retry cleanup
before another inspection and expose shutdown through the shared services,
CLI and MCP server. Serialize acquisition without delaying cancellation of
queued callers, and preserve primary diagnostics when CLI cleanup fails.

The original decoder reproduction left a live owned Node child with its
runtime deleted and no retained cleanup owner; the regression now verifies
retention, admission blocking, retries and eventual process/file cleanup.

Validation: 10 lifecycle/public CLI/MCP tests, 20 service tests, test
discovery 814/814, build:cached and full check including architecture guards.
Actual POSIX process/filesystem boundaries used injected Node workers on
macOS; real Linux pwntools/GDB provider parsing was not exercised.

* test(native): verify retained recorded-crash cleanup lifecycle

* fix(native): finalize diagnostic cleanup before publishing results

* fix(native): retire decoder stages before reading runtime evidence

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 01:37:47 +08:00
Ysopwnableandfactory-droid[bot] ad08510a11 refactor(evm): bind offline analysis through a static descriptor
Bind existing EVM CLI/MCP metadata and the legacy service factory through one static descriptor, and register the same selected service that owns cleanup. Preserve original names, schemas, inputs/full defaults, configuration, Evidence and injection identity.

Verified exact SDK catalog/fact parity across six real EVM pairs, 59 actual EVM CLI/MCP cases, six real cross-domain workflows, six actual Codex CLI fact/reference/lifecycle trials and relevant local checks. CI run 38283026233 succeeds for exact head d999d9874b. No token reduction from wiring or fully qualified resource claim; final counters remain unknown. Continues #2016.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-13 01:26:43 +08:00
Kaoru0822andClaude Opus 5.5 86de439ba4 fix(frida): name the argument each Frida input error rejects (#2217)
Frida session lookups, script lookups, unreadable script files and the
instrument-with-frida PID and script checks returned invalid_request with
no issues, while the remediation told callers to correct the listed
arguments. Attach the session_id, script_id, path, target or script issue
with the reason so CLI and MCP callers can see what to fix.

Fixes #2213

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:00:59 +08:00
e4d3e1399d feat(flutter): identify Dart snapshot builds and inspect AOT payloads by pure APK parsing (#1582)
* feat(flutter): identify Dart snapshot builds by pure APK parsing

Add a flutter-provider family with one operation, identify_flutter_build,
that reads an APK's lib/<abi>/libapp.so and libflutter.so through the
hardened ZIP reader and reports build facts as observations:

- The Dart VM snapshot hash, read 20 bytes after every snapshot magic
  (f5f5dcdc). The vm and isolate sections are cross-checked: agreeing
  sections collapse to one snapshot_hash, disagreeing sections keep every
  candidate with snapshot_hash null and partial coverage.
- Per-ABI library digests and byte sizes, plus the engine library's GNU
  build-id note and any labeled 'Dart VM version' or Android clang/LLVM
  toolchain strings, verbatim; release builds without a version string
  report null rather than a guess.
- The APK is digested before parsing so Evidence binds the observation to
  the exact input, and a target with no libapp.so reports not-detected
  with complete coverage.

The scanner is streaming with explicit pending-magic and rescan
bookkeeping, so chunk boundaries cannot double-count or drop sections, and
magic-free streams never accumulate. No engine, no external lookups: the
hash-to-SDK mapping stays with external datasets by design.

Verified against Flutter Gallery 2.9.2 (112 MB, three ABIs): every ABI
reports the same agreeing hash 65817c30a78bb44c3dc3771876b6010a from two
sections, per-ABI build-ids, and the clang toolchain line; a plain
aapt2-built APK reports not-detected with complete coverage. Scanner
goldens come from the same libraries. READMEs carry the new 'Flutter apps'
row in every supported language.

* feat(flutter): inspect Dart AOT snapshots through the ELF symbol table

Add inspect_dart_aot to the flutter family: for one ABI's libapp.so it
locates the four _kDart*Snapshot* symbols through the ELF dynamic symbol
table (ELF32 and ELF64 little-endian, bounds-checked reads; a payload
without exported symbols is refused), reports each section's offset and
size, validates data-section headers (magic, kind, length; instructions
sections honestly report nulls for the fields their layout does not
carry), and projects a bounded string pool from the isolate data section:
distinct package: source URIs (the app's dependency inventory), dart: SDK
URIs, and identifier-shaped tokens, each with counts, bounds, and partial
coverage when truncated.

The string pool is labeled as a byte-pattern projection, not deserialized
cluster semantics: typed class and function recovery remains an
SDK-specific parser, which the snapshot hash now unlocks. The ABI is
caller-selected with a deterministic default (arm64-v8a, x86_64, then
first available).

Verified against Flutter Gallery 2.9.2: all four symbols on both ELF64
(arm64-v8a) and ELF32 (armeabi-v7a) images, header validation, hash
agreement with identify_flutter_build, and a 756 package: / 201 dart:
URI pool from the isolate data section; goldens in DartElf.test.ts come
from the same libraries.

* fix(flutter): own snapshots, bound image reads, and preserve cancellation

Mirror the ownership bar the maintainers applied across the merged JEB,
ADB, and Apktool PRs:

- Copy the admitted APK into a provider-owned, read-only snapshot (EXCL
  create, chmod 0400) before digesting and parsing; every later read uses
  the snapshot, so a concurrently modified original cannot mix into one
  observation. The result reports the snapshot's byte size and digest.
- Retain failed snapshot-root cleanup in a provider set and retry it on
  close(), throwing an aggregate error when a root is still owned; root
  removal is injectable so the retention is testable.
- Allocate the AOT image buffer at exactly the declared library size
  before reading (bounded before allocation, not concat-after-stream),
  keep the 256 MiB ceiling, and check cancellation between digest and
  stream chunks through a captured abort reason.
- Accept APK paths containing spaces (covered by a fixture test) and
  escape the ABI pattern's dash for v-mode regex compatibility.

Also add tests for cleanup retention with close retry and for
cancellation before any snapshot root is created.

* docs(flutter): cover the Italian README with the Flutter row

The Italian translation landed between the merged feature PRs; its table
now carries every merged row plus this one, keeping its documentation-link
set identical to README.md.

* fix(flutter): make the ABI pattern portable for v-mode validators

Use a hex-escaped hyphen in the ABI character class, matching the form
the ADB portability fix uses, so clients compiling advertised schemas in
unicodeSets mode accept the inspect_dart_aot input schema.

* refactor(flutter): reuse shared harnesses and deduplicate the vertical

The duplicate-detection gate (jscpd, 2.5% threshold) tipped to 2.51% with
the flutter files added. Reuse the existing machinery instead of repeating
it:

- FlutterBuildAnalysisService delegates to executeProviderOperation, the
  shared admission/Evidence composition, instead of restating its body.
- The CLI registers both commands from one table-driven spec.
- Boundary tests use the shared serveCli and assertAdvertisedMcpContracts
  harnesses rather than hand-rolled equivalents.
- The provider test consolidates the four payload-shape cases into one
  table-driven case; the service test uses one admission table and
  distinct phrasings.

Duplicate lines fall from 2.51% to 2.48%, back under the gate.

* fix(flutter): address review findings from real-app verification

CassieFox23 verified the PR against three real F-Droid Flutter apps and
a control app, and found five gaps. All are fixed and re-verified against
cone (info.tangential.cone), one of the tested apps:

- Build-id: the scanner now reads the descriptor length from the note
  header instead of assuming 20 bytes, so 8-byte ids from older
  toolchains parse; the schema accepts 8-128 hex characters. Verified
  against cone's readelf-reported ids on all three ABIs.
- Compiler line: the toolchain capture bound rises from 200 to 500
  characters, keeping cone's 262-character clang line verbatim.
- Zero-byte libapp.so: the extraction target is created before streaming,
  so an empty entry yields a clean unsupported_target refusal for
  inspect_dart_aot and elf_header_valid: false with partial coverage for
  identify_flutter_build, instead of a raw ENOENT with code UNKNOWN.
- Truncated library: identify_flutter_build marks fewer than two snapshot
  sections as partial coverage with a limitation naming the count, and a
  missing ELF magic gets its own limitation.
- Docs: the default ABI preference now matches the code exactly
  (arm64-v8a, x86_64, x86, armeabi-v7a, then the rest alphabetically).

Also: every test that read the author's /tmp/opencode goldens now builds
a self-contained synthetic ELF64 image with dynsym, four snapshot
symbols, two snapshot sections, and a string pool, so the suite runs
anywhere; the verify lane now requires a present hex build-id per ABI
instead of accepting null.

* fix(flutter): address the Codex review findings

Eight findings, all applied:

- P1: SnapshotHashScanner keeps candidates in a Set (no quadratic
  Array.includes) with a 64-distinct-hash cap, so a hostile payload of
  magic+hash records cannot stall the scan or bloat the response.
- P1: projectStringPool stops admitting new distinct entries once each
  category reaches twice its projection bound and reports
  collectionCapped; allocation and sorting now track the response, not
  the payload.
- P2: ZIP reader rejections during entry iteration or entry streaming
  map into the typed error algebra (cancellation vs input refusal)
  instead of escaping as unhandled exceptions in both operations.
- P2: magic_valid now marks coverage only for the *Data symbols; a
  complete four-symbol image with valid data magics reports complete
  coverage (the instruction symbols intentionally lack the magic).
- P2: the MCP server closes the Flutter provider during shutdown, so a
  retained snapshot root is retried and reported, not leaked.
- P2: LabeledStringScanner commits matches only when a printable run is
  delimiter-terminated; the carry grows to 600 bytes so a 500-character
  toolchain line survives any chunk boundary untruncated.
- P2: both Flutter tool effects declare writesFilesystem: true; the
  owned APK snapshot and extracted libapp.so are temporary writes.
- P2: the verify lane asserts every ABI agrees on exactly one snapshot
  hash instead of discarding the computed set.

* fix(flutter): address the second Codex review round

Nine findings on the first-round fixes:

- P1: identify_flutter_build enforces a cumulative extraction budget
  (768 MiB) across every library entry, not just per library, so an APK
  with many ABIs cannot stream an unbounded total.
- P1: a single NUL-free printable run stops materializing at 1024 bytes
  and marks the pool capped, so an adversarial one-run section cannot
  allocate unbounded strings.
- P1: ELF cString bounds the NUL-terminator scan to the name maximum
  plus one, so malformed symbol tables cannot scan the whole image per
  entry.
- P2: mapReaderFailure distinguishes ArtifactReaderFailure texts —
  budget/limit rejections map to resource constraints, integrity
  failures (CRC/overlap/signature) to their own input refusal — instead
  of collapsing all reader failures into one message.
- P2: the labeled-string carry is cleared when a delimiter commits a
  run, so consecutive toolchain lines are never concatenated.
- P2: string-pool counts are renamed *_count_at_least and documented as
  lower bounds, because capped collection discards values beyond twice
  the projection bound.
- P2: inspect_dart_aot marks hash disagreements, non-pair source counts,
  and candidate-cap saturation as partial coverage.
- P2: only valid lowercase-hex hash records count as snapshot sources;
  complete magic records with non-hex fields do not inflate agreement.
- P2: the per-entry size refusal in inspect_dart_aot moves after ABI
  selection, so an oversized unselected ABI no longer refuses a small
  request.

* fix(flutter): address the third Codex review round

Five findings:

- P2: the owned snapshot revalidates the source after the copy (size,
  mtime, inode), so an in-place replacement or swap mid-copy refuses
  the observation instead of publishing mixed bytes.
- P2: a failed ZipArtifactReader close retains the snapshot root for
  close() retry instead of silently swallowing the descriptor leak,
  in both operations.
- P2: snapshot headers are parsed within their symbol bounds and a
  symbol smaller than the 16-byte header reports magic_valid false,
  so trailing-image bytes can no longer fake a valid data section.
- P2: the verify lane counts provider.close() cleanup failures as
  lane failures instead of certifying a run with retained roots.
- P2: LabeledStringScanner reports toolchain_capped when further
  distinct matching lines are observed past the 4-line projection;
  identify marks such results partial with a naming limitation.

* fix(flutter): address rounds three and four of the Codex review

Round three (one missed finding) plus round four (five findings):

- P2: the GNU build-id note descriptor size is decoded from all four
  bytes of the little-endian field, rejecting nonzero high bytes
  instead of masking them to 16 bits.
- P1: the Flutter MCP handlers route through createContractToolHandler
  and the session's analysisAdmission, so close_binary and snapshot
  operations drain in-flight Flutter calls instead of racing them.
- P2: the owned-snapshot copy is a streamed, abort-checked write (no
  copyFile), so cancellation stops the write promptly while the
  source-identity revalidation (size, mtime, inode) still guards
  against mid-copy replacement.
- P2: identify marks any snapshot_hash_sources value other than exactly
  two as partial, matching the inspection path's pair requirement.
- P2: the verify lane refuses to run without --apk (exit 2) instead of
  printing a false-green pass, and the engine check requires every
  libapp-carrying ABI to have a present libflutter with a valid hex
  build-id rather than filtering missing engines away vacuously.

* fix(flutter): address the fifth Codex review round

Six findings plus the upstream duplication baseline:

- P2: the flutter-provider kind reports available in the capability
  inventory, so binary_session no longer lists always-registered
  Flutter tools as provider_missing.
- P2: printable runs that exceed the 1024-byte cap are discarded at
  their delimiter instead of emitting their truncated prefix as a
  fabricated observation.
- P2: ELF symbols must fit inside the file-backed portion of their
  PT_LOAD segment (p_filesz), so addresses in gaps or BSS are refused
  instead of accepting unrelated bytes.
- P2: the build-id carry spans the complete 80-byte maximum note
  (16-byte header + 64-byte descriptor) so chunk-boundary splits
  cannot drop the first byte.
- P2: the labeled-string carry is sized for the toolchain pattern's
  true 605-byte maximum, not the previous 600.
- P2: the AOT completeness predicate requires exactly two sources and
  one candidate unconditionally, so zero-source images with valid data
  magics report partial instead of complete.

Also: the shared ELF fixture builder and snapshot-section helper moved
to a dedicated FlutterTestFixtures module, eliminating cross-file test
duplication; jscpd now passes at 2.50% while main sits at 2.52%.

* fix(flutter): address the sixth Codex review round

Five findings:

- P2: snapshot-hash scanning is bounded to the exported data symbols'
  byte ranges, so decoy or stale magic/hash sequences elsewhere in the
  image cannot inflate source counts or contribute candidates.
- P2: labeled-string runs longer than the carry bound are rejected
  instead of truncated, preventing a regex prefix from being published
  as a verbatim source string.
- P2: the AOT image reread checks cancellation between file reads and
  before the synchronous parsing stage, so a cancelled caller cannot
  receive a success from a completed 256 MiB read.
- P2: the verify lane requires exactly two snapshot sources per ABI,
  matching the provider's pair requirement, instead of accepting any
  count >= 2.
- P2: ELF section and program header entry sizes are validated against
  the class-defined minimum widths before walking either table, so
  undersized entries cannot cause field reads to cross into
  neighboring bytes.

* fix(flutter): address the seventh Codex review round

Six findings:

- P2: data-symbol ranges are deduplicated by offset and size, so aliased
  symbols mapping to the same bytes are scanned once and the result
  marks partial coverage with a limitation naming the shared range.
- P2: openEntrySafely forwards return/throw to the underlying Readable's
  iterator, so an early for-await exit closes the ZIP entry stream and
  releases its producer instead of leaking a backpressured pipe.
- P2: inspect_dart_aot now reports snapshot_hash_candidates and
  snapshot_hash_sources alongside snapshot_hash, so a null hash from
  conflicting evidence is distinguishable from missing hash data.
- P2: overlong printable runs only set toolchain_capped when they begin
  with a recognized label prefix (Dart VM version: or Android (); other
  long strings such as license text are skipped without marking partial.
- P2: readElfSymbol falls back to PT_DYNAMIC/DT_SYMTAB when section
  headers are absent (e_shnum 0, ET_DYN), so stripped Flutter libraries
  with exported snapshot symbols are no longer refused; the dynamic
  table is bounded by DT_STRSZ, DT_SYMENT, and the image end.
- P2: the verify lane exercises inspect_dart_aot for every ABI carrying
  libapp.so, not just the preferred default.

* fix(flutter): address the eighth Codex review round

Five findings:

- P2: each data-symbol range gets a fresh SnapshotHashScanner so the
  carry from one noncontiguous slice cannot fabricate a record spanning
  into the next; results are aggregated after scanning.
- P2: dynsym name lookups are bounded to the linked string table —
  st_name offsets outside the table and terminators beyond it are
  rejected instead of reading unrelated payload bytes as symbol names,
  in both the section-header and PT_DYNAMIC paths.
- P2: identify_flutter_build routes its reader.entries and reader.open
  calls through the same collectEntriesSafely and openEntrySafely
  wrappers as inspect_dart_aot, so malformed ZIPs surface as input
  refusals instead of AnalysisProtocolError.
- P2: mapReaderFailure recognizes ArtifactReaderFailure texts carrying
  a cancelled reason, mapping them to AnalysisCancelledError instead
  of AnalysisInputError.
- P2: the cumulative extraction cap is enforced inside the chunk loop,
  not after each library completes, so refusal happens before the
  remaining bytes are streamed and hashed.

* fix(flutter): harden streaming, sizes, and cancellation after self-review

Four issues found in a systematic self-audit across all bug classes
from eight Codex rounds:

- createReadStream in both the digest function and the owned-snapshot
  copy now receives the AbortSignal directly, so cancellation aborts
  the filesystem read at the source instead of waiting for the next
  chunk to arrive on a slow filesystem.
- The owned snapshot enforces a 2 GiB APK-level size cap before any
  copy I/O, so a path pointing at an enormous file is refused before
  disk usage grows.
- identify_flutter_build preflights the sum of declared entry sizes
  against the 768 MiB cumulative budget, refusing before any ZIP
  extraction when the declared total already exceeds it.
- The LabeledStringScanner triple result() call is collapsed to a
  single invocation (the previous code called result() three times in
  the emission, relying on end() being idempotent).

No behavior change for valid inputs; all 36 tests, check:fast, and
the cone verify lane pass unchanged.

* fix(flutter): require structurally parseable ELF headers for complete coverage

CassieFox23's third corrupt-header case: an ELF with valid magic but
zeroed section/program header offsets passes the 4-byte magic check
and the byte scanner still finds hash patterns in the data sections,
so identify_flutter_build reports complete coverage for a structurally
broken file.

The elf_header_valid check now also verifies beyond the magic:
e_type must be a known value (ET_REL/ET_EXEC/ET_DYN), at least one
of e_shoff/e_phoff must be non-zero, and at least one of
e_shnum/e_phnum must be non-zero. A file with valid magic but zeroed
structure reports partial coverage with the existing ELF-magic
limitation.

* fix(flutter): validate ELF and snapshot coverage

Share bounded ELF header parsing between identification and inspection. Accumulate headers across ZIP chunks and validate table entry widths and extents before claiming complete identification coverage.

Bind AOT hashes to the exported VM and isolate headers, validate stored snapshot lengths including the magic bytes, and preserve partial evidence for missing, malformed, aliased, or overlapping data headers.

Preserve native stream cancellations and APK resource constraints across both operations. Bound snapshot copies while streaming and retain useful input-failure diagnostics and lower-bound count wording.

Validation: 72 focused tests; check:fast; check including formatting; docs:check; test discovery; jscpd; real cone APK and non-Flutter control on Linux. Verified CLI/MCP parity for valid and corrupted ELF headers and AOT inspection across three ABIs. Native Windows and macOS were not run.

* fix(flutter): unify artifact ownership and bound ELF evidence

* fix(flutter): preserve ELF provenance and partial coverage

Read GNU build IDs only from bounded ELF note ranges and retain conflicting candidates. Preserve source versus owned storage failures and honor cancellation through parsing and final cleanup.

Separate snapshot structure from string-pool coverage. Verify every Gallery ABI with digest-bound engine labels and URI counts, and document the supported snapshot-kind layout.

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 22:35:55 +08:00
Daniel Gonçalves AraujoandN0zoM1z0 4a4ae9b2b9 feat: add Frida instrumentation support (#1359)
* feat: add Frida instrumentation support

* fix: resolve Frida CI checks

* test: cover Frida contract validation branches

* docs: link Frida instrumentation guide

* fix(frida): handle cancellation cleanup safely

* fix(frida): address PR review findings

* fix(frida): preserve resume and message observations

* fix(ci): use canonical registry for rolldown

* fix(frida): declare foreign code effects

* fix(frida): retain failed startup resources for cleanup retries

Keep failed startup session and spawn handles owned until detach, resume,
and remote lease cleanup complete. Serialize retries and release each
remote reference once. Await CLI provider cleanup while preserving the
primary failure and any completed observations.

Add regressions for retained startup resources, concurrent cleanup,
shared remote leases, and CLI cleanup outcomes.

Validation: 41 focused tests pass on the PR head and its latest-main
integration; serial static and docs checks pass. Real Linux Frida 17.23.2
workflows and the native spawn/controlled-failure cleanup probe pass.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

---------

Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-12 22:01:58 +08:00
Ysopwnableandfactory-droid[bot] 0b7145361e feat(wasm): add opt-in first-call summary delivery (#2193)
Add explicit first-call WASM summary delivery while preserving omitted/complete MCP requests, CLI output, original Evidence identity and provider inputs. Reuse exact retained export views and schema-based capability discovery.

Nine paired public SDK comparisons and ten actual Codex CLI answers preserve selected facts and source references. Record token reductions alongside mixed latency and unverified final resource-counter conditions. Current-main integration passes seven relevant WASM MCP workflows, a fresh real-WABT SQLite workflow and required static gates. Refs #2016.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-12 22:01:47 +08:00
Kaoru0822andClaude Opus 5.5 7c9c1ebdb7 fix(mcp): keep shared optional providers open across discarded probes (#2205)
startMcpTransport loads optional observation providers once per process
and passes them to every server instance the SDK constructs. Each
instance's closeProviders also closed the shared browser scenario
provider, so when the SDK discarded a server/discover probe instance for a
legacy initialize, every later capture_browser_scenario call failed with
"Browser scenario provider is closing." Server instances no longer close
the caller-supplied provider; the transport returns
closeOptionalProviders and process shutdown closes it once.

Fixes #2195

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 06:56:45 -07:00
Ysopwnableandfactory-droid[bot] 58fb372071 feat(analysis): add opt-in retained inventory and WASM views (#2122)
Add opt-in retained inventory and WASM Evidence views with exact nested output contracts and a small static WASM descriptor. Preserve old complete CLI/MCP workflows, producer choices, original authenticated Evidence and cleanup ownership.

Validated with real public applications, genuine old Evidence migration, 123 focused assertions, 11 synchronized description checks and 42 installed-package WABT cases. Detailed generated experiment JSON stays outside the final tree; concise findings and reproduction inputs remain. Main-existing completion/package CI failures are separately attributed and left unchanged.

Refs #2016

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-12 21:17:52 +08:00
morluto 07b36c1489 fix(mcp): keep prompt completion within ready provider sessions
Avoid lazy provider startup for document and procedure completion. Propagate MCP cancellation through completers, cancel lookups during session transitions, and share provider result projection with ordinary operations. Cover cold, starting, warm, queued, cancelled, and closed sessions through MCP composition and provider boundaries.
2026-10-12 16:27:51 +08:00
morluto d8c76b6296 fix(io): retain cleanup ownership and honor cancellation
Keep failed JSON read handles in the existing server resource scope and fail admission until cleanup succeeds. Thread cancellation through every process CLI input read and replace timer-driven cancellation checks with a shared first-read gate.

Classify authenticated standalone Evidence as wrong-kind input while preserving tampered-record integrity failures and actionable messages across ledger, CLI, and MCP consumers. Record unrelated CS_RESTRICT process neighbors as unverified without weakening related-process ownership checks. Update stale ADB fixtures for the actual shell protocol.

Validated focused CLI, MCP, filesystem, ownership, and error projection tests; static, docs, and duplication gates pass. The host-level CS_RESTRICT load reproduction was not run. Refs #2050, #2035, #2064.
2026-10-12 14:12:44 +08:00
morluto 3bcc68c037 fix(evidence): enforce managed identity and cancel bundle reads
Validate managed reconstruction through the shared artifact and MVID scope boundary, including known/unknown identity contradictions. Forward MCP comparison cancellation into both bundle reads and consolidate pre-cancel coverage.

Verified managed graph/reconstruction and filesystem/MCP cancellation workflows. A controlled missing-signal mutation reads 130 chunks instead of the expected one; cancellation leaves the session unchanged and retry succeeds.
2026-10-12 13:06:30 +08:00
You Wishandmorluto a1b5d51a8d feat(go): inspect embedded binary build metadata (#1363)
* feat(go): inspect embedded binary build metadata

* fix(go): preserve byte metadata and validate container mappings

* fix(go): support moduleless legacy build metadata

Recognize optional module string headers in declared zero-filled memory while rejecting ambiguous and unmapped pointers. Preserve the original module-pointer field as the zero-byte source anchor.

Classify initial symlink-loop and overlong-path failures as invalid input, with CLI and MCP regressions.

* fix(go): reject undersized PE optional headers

* fix(native): stabilize ELF memory checks and clean up exec wrappers

Use existing parent/group/run-token ownership for caller-selected Python launchers, which can exec through a shell or prlimit. Add cancellation regressions for the valid wrapper and wrong-parent/token cases.

Replace the timing-dependent 30,000-section memory workload with a valid 32 MiB padded ELF under a 64 MiB address-space limit. Check the same image successfully through CLI and MCP before requiring a typed memory failure, preserving the production timeout and all error assertions.

Validation: npm run check and check:fast passed; 61 focused tests passed including Go CLI/MCP and session snapshots. Real decoder probes with pinned packages passed on Python 3.12.3 and 3.12.14. The full local ELF verifier is blocked by this container's procps/process-ownership boundary; the exact pushed head requires GitHub's real-binary-layout lane.

* test: repair Electron fixtures and stabilize catalog startup checks

Declare Electron imports in option, preload override, and path-resolution fixtures after upstream began requiring proven API provenance. Retain all option and preload assertions and adjust exact source ranges for the added import line.

Use the existing bounded acceptance timeout for the cold catalog lifecycle test instead of a separate 15-second ceiling. This retains the coverage allowance and all catalog, error, and cleanup assertions without retries.

Validation: npm run check, final check:fast, formatting and diff checks passed. Source path regression and Go boundary/MCP/service checks passed. All 20 Go CLI cases and both supported-host runtime cases passed on rerun; two macOS-only cases skipped on Linux. A prior contended local run timed out once in a Go CLI diagnostic; that case passed on rerun. Electron process-boundary verification is blocked locally by procps namespace inspection and requires fresh CI.

* test(mcp): isolate nested schema references between tool contracts

Clear Ajv's non-meta schema registry after each root, including compilation failures. Disabling root registration alone leaves nested IDs available to later tools and can let a dangling reference pass the catalog gate.

Add regressions for leakage after successful and failed compilation while retaining shared meta-schema validators. The regression failed before the fix; all 11 schema cases and full npm run check pass. Reviewed independently.

* test(ci): align Go effects and source-map verification contracts

Audit the Go inspector wording as static metadata inspection. Assert retained source declaration indexes in BOM reconstruction and the compiler-derived nested-map oracle. Keep a 45,000-map admission control below the 32 MiB output budget and the 50,000-map overflow case above it with the expanded representation.

Validation: reproduced all four failing assertions, then passed 120 focused tests and the final admission suite. npm run check and real Chrome 154 / esbuild 0.25.10 source-map verification passed, including all four nested-map scenarios and verified process lineage.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 11:34:02 +08:00
morluto e19879328a refactor: prune obsolete provider and verification code
Remove unused imports, private inferred types, superseded limit constants and a duplicate MCP assertion. Preserve intentional field omissions while deleting unused local bindings.

Validation: typecheck, lint, formatting, unused-code and architecture checks pass. Runtime behavior is unchanged.
2026-10-12 08:59:14 +08:00
a149d183ef feat(managed): select declaring types in inspect_managed_members
Select exact declaring types before managed signatures and CIL bodies are decoded, preserving caller choices in CLI/MCP Evidence. Keep unmatched names and selected coverage explicit; comparisons and graphs retain unknowns outside their observed scope. Reuse existing metadata ownership/accounting and advertise unique selections through the actual SDK Schema.

Validated with 229 focused tests across 21 files, 11 managed conformance controls, fullstatic/docs checks and real Linux CLI and fresh MCP inspection of two unchanged DLLs. All 118 selected CIL hashes matched original PE-mapped bytes; result/caller-argument parity and unmatched controls passed. Full artifact/native-boundary metadata is complete; whole-assembly members retain the unchanged 64 MiB resource constraint. No target code executes.

Refs #1878

Co-authored-by: skared <190618464+skoodster@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-12 08:31:37 +08:00
YsopwnableandKaoru0822 6395e8d300 perf(mcp)!: compact repeated session discovery facts (#1988)
Group repeated session tool availability and provider capability facts, preserve complete named contracts and ordered limitations, and remove duplicate catalog descriptors. Update consumers and migration guidance.

Validated by all 31 CI jobs, focused source checks, and actual Claude Code/Linux Hopper/native Windows Ghidra small-target workflows on the current integration tree.

Refs #723.

BREAKING CHANGE: binary_session no longer includes server_identity.catalog.tools; tool_availability and provider capabilities use grouped facts documented in docs/mcp-contracts.md.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-12 07:40:19 +08:00
morluto 7285e15839 fix(workflows): retain staged output ownership and cancellation semantics
Give atomic Evidence and snapshot writes an explicit resource owner, preserve primary failures and completed publication receipts, and retry retained staging cleanup at the owning lifecycle. Verify inode identity before publishing or deleting; unknown path disappearance remains a cleanup failure. Keep snapshot admission reusable when a session closes and reopens.

Consolidate JavaScript source-scope classification so cancellation cannot fabricate failures for unselected files. Classify configuration failures as invalid input. Remove stale assertions and reuse shared test cleanup ownership.

Validation: 266 focused tests before final ownership tightening, 108 affected tests afterward, static and documentation checks, actual invalid-configuration CLI behavior, and isolated test temporary-directory hygiene.

Refs #1968
2026-10-12 06:29:27 +08:00
morluto 264615059c refactor(mcp): trust validated inputs and tighten contract fixtures
Remove repeated MCP input parsing after the SDK has validated named contracts. Reject unmodeled fixture operations and locate prompt contracts by name so unrelated catalog ordering cannot select a contract.

Validated focused browser, Electron, runtime-observation and MCP workflow tests, advertised schemas, packaged MCP and static checks. Application-boundary validation remains in place.
2026-10-12 05:57:35 +08:00
morluto 9c8511409c fix(analysis): preserve relationship coverage across evidence and replay
Separate observed relationship coverage from general provider caveats. Authenticate and replay coverage without changing legacy Evidence IDs; expose unknown and capped relationship sets through CLI/MCP graphs and traces.

Validated focused domain, snapshot, IDA/Ghidra boundary, MCP, schema, package and static checks. Provider fixtures establish contract behavior; licensed engine behavior was not reverified.
2026-10-12 05:57:35 +08:00
morluto a82e37c806 fix(browser): retain module resolver cleanup ownership
Serialize resolution with shutdown, retain the owned browser after close failures, and retry cleanup before another launch. Wire cleanup through the shared service and CLI/MCP lifecycles, preserving primary failures and completed native reports alongside cleanup diagnostics.

Separate the browser resolution workflow from lifecycle ownership. Validation: seven resolver source tests, eleven application tests, MCP shutdown retry, public CLI parity, and full static/architecture checks passed. Real Chromium behavior remains unverified.
2026-10-12 04:44:25 +08:00
1449e8e051 fix(mcp): provide native evidence paging continuation
Supply schema-validated inspect_analysis_view arguments after completed native function Evidence is recorded and exceeds MCP delivery capacity. Preserve the full canonical result and its provenance. Verify exact source paging, export and following-call usability through real Ghidra stdio MCP.

Fixes #1849

Co-authored-by: Minghang Chamling <133689405+cold-atom@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-12 04:26:05 +08:00
Itoje Dollar e4ac7bbfc2 fix: order remaining outputs independently of host locale (#1867)
* fix: order remaining outputs independently of host locale

String.prototype.localeCompare without a pinned collation follows the
host's ICU default locale, so the same input could be ordered differently
on different machines. 614fb768 moved canonical domain projections to
compareUnicodeCodePoints; provider, application, catalog, and setup
orderings still used locale collation.

Order every remaining source site by Unicode code point, including Mach-O
symbols, firmware extraction paths, ASAR entries (previously pinned to
"en" collation), evidence ID sets, browser and Electron target, script,
and resource inventories, reconstruction obligations, capability and
provider listings, and setup environment details.

The current tool and prompt catalog names order identically under both
comparators, so the catalog identity digest is unchanged.

* fix(artifacts): order ASAR entries by their portable path

@electron/asar lists host-spelled paths, so code-point order over the raw
spelling still differed by host: "a\b" sorts after "a0" on Windows while
"a/b" sorts before it on POSIX. Pair each listing with its portable
archive path once, order by that path, and keep the host spelling for
@electron/asar calls and adapter keys.
2026-10-12 01:10:01 +08:00