* feat(apple): inspect IPS crash reports
Add inspect_apple_ips for caller-selected Apple .ips files. Parse the
first-line metadata object and, when bug_type is the string 309, the
crash body: process identity, exception and termination facts, threads,
usedImages, lossless integer registers, and documented classification
rules. Other bug types including 288 stackshots return no crash result.
Opened Mach-O and dSYM UUID joins remain unobserved.
Related to #4297
* fix(apple): keep IPS register literals exact
Use the arm64e fixture integer that matches 0x8527000193ed4944 instead
of an IEEE-754-rounded decimal, and count the lossless JSON example
length from the source text.
* fix(apple): budget IPS parsing and keep typed presence
Parse the IPS metadata and crash body through a projection of the
documented members. Members the report does not interpret are
syntax-checked without being materialized, and thread, frame, image and
the new max_registers budgets run before each row is parsed, so a large
selected file fails with a typed resource error instead of first
expanding every row. Fixed allowances bound JSON nesting, unlisted key
names and termination reasons.
Present values whose JSON type differs from the documented one are no
longer read as absence: they are listed in coverage.type_mismatches and
coverage becomes partial, including wrong-type or missing threads and
usedImages collections. osVersion keeps the producer dictionary or the
string form. Frame roles follow physical frame depth, so the top frame
of a non-faulting thread is current_instruction and inlined rows share
the following frame's role. SIGKILL classes compare the canonical hex
once, so 0xdeadd0cc no longer matches dead10cc. Invalid UTF-8 is refused
instead of being replaced, and JSON strings are decoded by copying
unescaped spans.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ra7LM2NyQ7DumdssxbUq5g
* fix(apple): bound integer text expansion and reconcile coverage
* refactor(apple): retain image metadata at its owning row
* refactor(apple): validate row capacity through reconciled coverage
* test(apple): verify resource recovery at the public error boundary
* docs(apple): record complete IPS task and corpus measurements
* docs(apple): record integrated checks and stdio corpus evidence
* docs(apple): record PE integration and baseline cleanup controls
* fix(native): bound IPS string decoding and preserve invalid identities
* refactor(native): use exact optional IPS source evidence
* docs(native): verify IPS escape capacity and complete-task costs
* test(native): verify IPS through production stdio MCP
* style(tests): format IPS advertised schema bindings
* fix(native): preserve unresolved IPS references and recorded frame semantics
* docs(native): record IPS reference review evidence
* fix(apple-ips): enforce JSON and report consistency
* docs(apple-ips): record final consistency verification
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
* feat(pe): inspect import and delay-load tables
Add inspect_pe_imports / inspect-pe-imports to read PE32/PE32+ import
and delay-load directories without executing the image. The report keeps
DLL names, named and ordinal functions, ILT/IAT RVAs, and a pefile
import hash of the standard import table. A missing directory is
observed absence, not proof the image never imported APIs.
* fix(pe): default PE import fixture options
Allow peImportImage() without an argument so CLI and filesystem tests
can use the KERNEL32 sample without repeating an empty options object.
* test(pe): keep import path cases on the dedicated MCP contract
inspect_pe_imports already rejects relative MCP paths in its own
boundary test. Leave the shared absolute-path matrix to tools whose
handler issue projection matches that suite's expected shape.
* fix(native): index virtual-to-file mapping lookups
mappedFileOffset scans every mapping twice per span, so a parser that
translates one span per table entry costs sections x entries. Add
fileMappingLookup, which builds an O(n log n) interval index once and
answers each span in O(log n) with the same accept, reject and
translation results. A differential test checks it against
mappedFileOffset over randomized overlapping mappings and zero fills.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ra7LM2NyQ7DumdssxbUq5g
* fix(pe): report partial import evidence and exact pefile hashes
- Withhold imphash with an explicit reason whenever the standard import
table is partial (unreadable names or thunks, missing tables), or when
pefile 2024.8.26 would hash a different row sequence: invalid or
truncated names, ordinal 0, descriptors without functions, tables its
bounds or repeat/spread heuristics discard, and its 8192-thunk import
symbol cap. Delay-load issues do not withhold it.
- Hash ordinal imports with pefile's complete ordlookup tables and its
ord<decimal> fallback instead of declining unmapped ordinals.
- Report a nonterminal descriptor whose FirstThunk is zero, and a
delay-load descriptor whose IAT or INT RVA is zero, as malformed_entry
partial coverage instead of a complete empty inventory.
- Directory evidence lists the file spans actually consumed for the
descriptor array and terminator; discontiguous mappings produce
separate spans and separate Evidence ranges.
- Carry exhausted limits as PeImportLimitFailure.limit and derive
recovery from it; the fixed 16 MiB retained-text ceiling reports a
fixed allowance instead of max_file_bytes advice.
- Translate RVAs through the indexed mapping lookup and yield with a
cancellation check every 1024 table entries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ra7LM2NyQ7DumdssxbUq5g
* fix(pe): read only own ordinal tables for DLL names
DLL names such as constructor and __proto__ pass pefile's name rule but
resolved inherited object members, throwing before the ord<n> fallback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ra7LM2NyQ7DumdssxbUq5g
* fix(native): preserve PE import facts and prove hash compatibility
* test(native): verify PE import workflows and measured costs
* refactor(native): narrow PE facts across the container union
* docs(native): record integrated PE import validation
* fix(native): bound every PE import RVA span
* docs(native): measure RVA guard completed workflows
* fix(pe): reconcile import coverage with retained rows
* fix(pe): retain partial imports at descriptor mapping gaps
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Reuse validated class pages for inline pagination audits while retaining complete provider replies. Move retention into the shared Android workflow and remove the MCP-only service wrapper and application text reparser. Preserve unknown JSON metadata, late cancellation and retention failures.
* fix(mcp): report Linux-only integrations as unsupported_host off their hosts
Session discovery folded the host check into each optional integration's
enabled flag, so on macOS or Windows the Linux-only packet, signal,
firmware, pwntools, EVM and Wakaru tools reported provider_missing.
Their execution guards refuse those hosts whatever is configured, so
installing a provider there could never make them available.
The server now records, per integration, when the host is outside its
verified host and no service is injected. Discovery checks that before
configuration and reports unsupported_host with the existing
remediation. Injected services and supported hosts behave as before.
Fixes#5730
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(mcp): share provider host checks with session discovery
Discovery restated each Linux-only integration's host rule in
createServer while its provider kept a separate execution check, so the
two could drift apart again. Each provider now exports its host
predicate, uses it in its execution guard, and composition hands the
same predicate to createServer for both the host restriction and the
enabled flag.
Observed host restrictions now also apply when an embedder supplies its
own availability policy, as provider load failures already do, because
no policy lets the default providers pass their host checks.
The MCP regression moves to tests/process-global and emulates darwin
arm64, linux arm64 and linux x64 through the real createServer, so CI on
Linux x64 exercises the unsupported-host branch. It also covers a
configured policy and the matching execution refusals.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(mcp): keep caller host restrictions beside observed ones
The observed host restriction replaced a configured policy's whole
hostUnsupported map. For an injected service the observed value is
false, so a caller's own restriction was lost and the tool was reported
available. Combine both per integration: either the caller or the
observed host can mark it unsupported.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(pcap): expect unsupported_host for packet tools off Linux
The host-independent PATH case asserted provider_missing on every host.
Off Linux the packet tools are unavailable because of the host, so
discovery now reports unsupported_host there; Linux still reports
provider_missing for an unusable PATH.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(pcap): give TShark selection and version admission one owner
The pcap and packet-capture families wrapped the same caller-supplied
TShark with diverging rules. inspect_pcap_* accepted an absolute
REA_TSHARK_COMMAND or tshark from PATH, while inspect_packet_* and the
server availability policy required an absolute REA_TSHARK_COMMAND and
parsed the version banner with a separate regex.
PcapConfiguration now owns the rule: selectWiresharkTool selects an
absolute environment path or the bare name on PATH and refuses relative
values; locateWiresharkTool resolves a PATH selection to the first
absolute PATH entry holding an executable file; parseWiresharkVersion
admits Wireshark 4.x banners for both providers. TsharkCaptureProvider
and the session availability policy consume these facts instead of
reinterpreting REA_TSHARK_COMMAND, so all four tools accept and refuse
the same configurations. inspect_packet_* still resolves, hashes and
rechecks the located executable, and records selection_source in its
tool Evidence.
Host support and resource bounds are unchanged; unifying them is the
next milestone in #3403.
Refs #3403
* fix(pcap): execute the TShark the shared locator selects
resolvePcapTools still returned bare tool names for PATH selections, so
the operating system could run a tool from a relative PATH entry while
the packet tools skipped that entry and selected a different install.
On POSIX hosts, resolve PATH selections through locateWiresharkTool and
run that absolute executable, failing with the existing tshark_missing or
capinfos_missing code when no absolute PATH entry holds the tool. Both
selections are validated before PATH is consulted, so a relative
environment value still reports its own configuration error. Windows
keeps PATH/PATHEXT resolution in the process launcher.
Refs #3403
* chore: restore main's copies of files the merge hook reformatted
The pre-commit oxlint --fix touched two files this PR does not change; keep them identical to main.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pcap): share selected tool identity verification
* perf(pcap): retain compact executable identity
* fix(pcap): report missing selected tools clearly
* fix(pcap): read historical capture evidence
* fix(pcap): preserve executable read failures
* test(pcap): cover version refusal and packet-tool availability selection
Address review follow-ups on the shared TShark owner:
- Send a 3.x TShark banner and a non-Wireshark banner through the packet
provider, pinning the capability-unavailable reason for each and that
only the version probe ran before refusal.
- Cover the session availability rule for inspect_packet_capture over
MCP: a PATH-only install and an absolute REA_TSHARK_COMMAND are
available on Linux, a relative REA_TSHARK_COMMAND is refused even when
PATH holds TShark, and no absolute PATH entry reports provider_missing.
- Rename the locator test's missing absolute PATH entry so it no longer
shadows node:path relative.
Refs #3403
* fix(pcap): name the configured path when a selected tool is missing
Resolving the selected executable before launch replaced the runner's
"Cannot run selected tool <path>" refusal with a message that kept the
configured path only in diagnostics, so the public CLI no longer told the
caller which REA_TSHARK_COMMAND or REA_CAPINFOS_COMMAND value to fix and
the pcap CLI boundary test failed. Include the configured command in the
capability-unavailable message and assert it there.
Refs #3403
* test(captures): give the late-cancellation fixture a TShark selection source
The service fixture added on main in 719d56ebf predates the required tool.selection_source field, so its report failed output validation before reaching the late-cancellation path the test covers.
Refs #3403
* fix(pcap): report a probe's pending cleanup when a post-run check fails
When a tool probe returned with its owned process still awaiting cleanup,
a failed post-run executable re-read or identity check threw before run()
reported that cleanup. Probes have no snapshot to carry it, so callers
saw an ordinary error with cleanupIncomplete false while the provider
kept the process and refused the next request.
After the command returns, combine such a failure with the probe's
ProviderCleanupError (cancellation and other command failures keep their
own cleanup outcome). Classify request failures through one
analysisFailure owner shared by run() and executeAdmitted(), and let the
availability probe rethrow any cleanup-incomplete failure instead of
reporting the tool unavailable.
Refs #3403
* fix(pcap): keep a failed executable re-read's cleanup live with the probe's
The combined post-run failure was bound only to the probe's pending
process cleanup. When the executable re-read had also failed to close its
file, the classified failure owned that cleanup, but the combined error's
live cleanupResources omitted the file and could clear cleanupIncomplete
once the process stopped. Bind both the classified failure and the probe
cleanup as dependencies.
Refs #3403
---------
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>
* fix(mcp): escalate transient failures before asking for a restart
Give dropped connections and startup failures one bounded retry, then a
scripted handoff to the user. Point timeout recovery at a named request
field or REA_* setting instead of telling agents those limits are fixed.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(process): stop unexpected command failures from recommending a retry
The catch can already have launched the target, and the projection stays
non-retryable. Tell the user to check the inputs and run doctor instead.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(mcp): limit retries to safe calls and recommended settings
A dropped connection may already have changed the target, and a bad
catalog rejects the same startup every time. Retry only a repeatable
call, and change a setting only when the remediation recommends it.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* test(mcp): match recovery guidance across wrapped lines
Startup handoff capitalization and markdown wrapping still carry the
same sentences. Compare the prose with whitespace collapsed.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
* feat(python): inspect CPython pyc headers and marshal code objects
Add inspect_python_pyc / inspect-python-pyc to read one explicit local
CPython 3.7–3.13 .pyc without executing bytecode or recovering source.
* chore(python): drop unused PythonPycHeader export
Knip reported the type as unused after inspect_python_pyc landed.
* fix(python): bound pyc expansion and decode marshal like CPython
- Count a nested code object reached through TYPE_REF once per copy the
report carries, against max_objects and max_file_bytes, before counting
or validating the tree
- Charge long digits to max_string_bytes, reject out-of-range and
unnormalized digits, build the value in one pass, and report integers
above 256 bits by bit length only
- Decode TYPE_UNICODE with surrogatepass semantics and reject other
ill-formed UTF-8
- Map only 3.11 magics 3494-3495 to the py311 layout
- Report non-finite float and complex parts as inf, -inf or nan
- Allow an empty co_filename
- Require bytes for co_linetable and co_exceptiontable
- Bind cleanup-failure errors to their retained descriptor leases
* fix(python): list pyc code objects once instead of a recursive tree
Report each distinct code object once in code_objects, top-level first,
with nested_code as indexes. A child shared through TYPE_REF is no longer
copied per reference, and the MCP output schema is no longer recursive.
Names repeated through TYPE_REF still count against max_file_bytes for
each copy the report carries.
* fix(python): bound shared pyc constants and reject malformed tables
- Cache byte-string digests so a buffer shared through TYPE_REF is
hashed once instead of on every reference.
- Charge every reported co_consts entry, including tables shared
through TYPE_REF, against max_objects before summaries are built.
- Resolve the inspect-python-pyc path with absoluteCallerPath so
link/../file.pyc reads the file the filesystem selects.
- Reject TYPE_NULL inside marshal sequences, as CPython does.
- Reject a co_localspluskinds length that does not match
co_localsplusnames in the parser and the report schema.
* fix(python): bound shared pyc names and read CPython marshal graphs
Charge each reported code-constant name, keep integer bit lengths on the
decoded value, and list code objects nested inside constant containers.
Accept self-referential lists and dicts, marshal version 0 text floats,
empty code names, the original string byte count, and Python set and dict
lengths. Pass the CLI cancellation signal into command cleanup.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): bound pyc key expansion and shared nested code
Charge set and dictionary keys before a shared tuple doubles them, list each
nested code object once per owner, and accept code objects as CPython keys.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): correct pyc equality, counts, and nested walks
Summarize code objects only after the marshal graph is complete, and
collect nested code with an iterative walk that shares wrapper results
instead of copying every descendant list. Keep tuple boundaries and the
original string bytes in equality keys, and reject negative CPython counts.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): bound shared pyc names and keep the first dict key
Charge every copied name-table entry against the object budget before
building the report array, including empty strings that add no bytes.
When dictionary keys compare equal, keep the first key object and
replace only its value, matching CPython.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): walk each pyc dictionary child list once
Keep a container's child array on the nested-code frame so a wide
dictionary is not copied on every step of the synchronous marshal walk.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): reuse stored pyc dictionary children when combining
The nested walk keeps each container's child list on its frame.
Combining nested code rebuilt that list, and the 8,000-key regression
still accepted the old per-key copy. Use the stored list, and require
that dictionary to finish well under the copy's runtime while still
reporting a nested code object.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): keep distinct pyc code objects and reject corrupt ones
Encode each name table's length and entry boundaries in the equality
key so a different name list cannot share a memo key. Walk tuple and
frozenset keys on an explicit stack so a long TYPE_REF chain does not
overflow. Treat code objects CPython rejects for an odd co_code or an
undersized local table as malformed instead of complete coverage.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
* feat(erlang): inspect BEAM IFF chunks and tables
Replay the Erlang BEAM inspection workflow, including table bounds,
OTP 28+ atom layouts, the shared absolute-path policy, and empty-path
CLI coverage, without carrying GitHub workflow edits.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(erlang): use publicInputStrictObject for BEAM tool input
inspect_erlang_beam advertised a public input built with bare
z.strictObject, so later shared input-policy changes would miss it.
Result and internal objects stay on their own constructors.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
* feat(pe): inspect Authenticode certificate tables
Add inspect_pe_certificates for IMAGE_DIRECTORY_ENTRY_SECURITY
WIN_CERTIFICATE entries and structurally decoded PKCS#7 signer
and X.509 identity fields. The workflow reads a stable PE image
without executing it or verifying signatures, chains, timestamps,
or Authenticode digest coverage.
* fix(pe): bound and validate certificate DER decoding
- Cap decoded DER values with a shared node budget so sibling fan-out
cannot exhaust memory before the PKCS#7 check
- Require SignedData version, encapContentInfo and a final signerInfos
SET in RFC 5652 order, and a signature OCTET STRING in each SignerInfo
- Decode OBJECT IDENTIFIER arcs as unbounded base-128 values, including
a multi-byte first combined arc
- Decode UniversalString names as UTF-32BE and reject invalid values
- Share PE header admission with the resource layout so a section table
that does not fit SizeOfHeaders is rejected
* docs: list PE certificates in the translated READMEs
* fix(pe): cap OBJECT IDENTIFIER length and arc size
A crafted type-2 certificate with a 262,144-byte contentType OID stalled
decodeOid for about 20 seconds, because one arc kept growing a BigInt
before the signedData check ran. decodeOid now rejects an OID longer than
256 bytes and an arc longer than 32 bytes before decoding it. Certificate
OIDs, including 2.25 UUID arcs, fit under both caps.
* fix(pe): reject truncated certificate tables and PKCS#7
SignedData now requires one SignerInfo with a non-empty signature and a
complete issuerAndSerialNumber. Certificate names share a 64 KiB decoded-byte
budget and are copied once. A security directory that ends in a short
WIN_CERTIFICATE header fails instead of reporting a complete table. The
certificate CLI forwards the caller abort signal into cleanup.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* chore(ci): keep fork workflow files unchanged
The certificate restack follows current main. Workflow files stay at the
fork tip so this branch update does not rewrite .github/workflows.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(pe): charge serial and validity text to the decoded budget
Certificate and signer serial numbers and validity times now count against
the shared decoded-text budget before they are converted, so a crafted
certificate cannot push megabytes of text into the hashed evidence. The
budget error now names certificate text rather than only names.
Restore the CI workflow to match main: the CI_TIMING_TIER input, the
tier-named timing artifacts and their publication conditions, the Windows
typecheck, and the path and snapshot suites in the curated Windows lane.
* fix(pe): require certificate fields and preserve signer key ids
Reject X.509 records that omit subjectPublicKeyInfo or signatureValue,
return subjectKeyIdentifier bytes as bounded hex, and advertise an absolute
path in the PE certificate input schema.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(pe): reject extra PKCS#7 wrappers and invalid UTF-8 names
ContentInfo and its signedData wrapper no longer ignore trailing values, and
directory strings must round-trip as UTF-8 instead of becoming U+FFFD.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* feat(native): read PE and ELF export tables
Add a host-independent export-table reader on the shared native
container layer. PE images report each used export-address-table slot
with its ordinal, one row per name, its address or forwarder text, and
the export directory identity; the PE image reader now exposes its data
directories. ELF images report defined default/protected global, weak
and unique .dynsym symbols with type, binding and .gnu.version_d
version (hidden versions kept distinct, unreadable version tables
"unknown"). Unreadable entries are counted in issues and make coverage
partial; an ELF without section headers is unsupported.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(native): inspect native export tables through CLI and MCP
Expose the reader as inspect_native_exports / inspect-native-exports:
one stable, digest-bound read of an explicit file with a caller-selected
input budget, typed failures for malformed, unsupported, oversized and
cancelled reads, and observed Evidence bound to the file path and
SHA-256. Mach-O inputs point to inspect_macho.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(native): describe portable PE and ELF export inventories
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(native): bound export inventories and read header-backed PE tables
Address review of the export-table reader:
- Charge every retained row and its name, forwarder and version text
against shared 262144-row and 16 MiB allowances before storing it, so
repeated long names or PE aliases cannot exhaust memory.
- Map PE RVAs through the headers as well as sections; the PE image
reader now exposes its SizeOfHeaders mapping.
- Keep ELF exports with version "unknown" when .gnu.version lies outside
the file, and report an empty version-definition name as unresolved.
- Reject a .dynsym without its mandatory null entry as malformed.
- Decode the ELF section directory once.
- Correct the docs on which gaps drop rows and which keep them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Inspect selected ELF32/ELF64 PT_NOTE and SHT_NOTE declarations without executing
the artifact, retaining independent table identities, source ranges, descriptor
digests, GNU build-id/ABI fields and explicit coverage limitations.
Integrate mvanhorn's implementation and hardening with current main while
preserving byte-entropy registration and the Windows curated regression suite.
The maintainer follow-up uses ordinary merges/pushes, not history rewriting.
Executed validation: 96 focused/shared/docs tests, complete static/docs checks,
eleven real CLI/MCP pairs including GCC ELF32 and Clang big-endian PowerPC64,
and two actual Codex task traces checked against their Evidence. Full costs,
grader correction and verification limits are recorded in PR #4837.
Refs #6262.
* feat(diagnostics): report a byte entropy profile for one local file
The diff adds the MCP tool inspect_byte_entropy and the CLI command
inspect-byte-entropy, both implemented by ByteEntropyService. One
absolute regular file is read offline into observed Evidence: file-wide
SHA-256 and Shannon entropy, then fixed blocks and adjacent runs for an
optional window, using a power-of-two block size from 256 to 65536
(default 4096), with high at 7.2 or above and low at 1.0 or below. A
window past EOF, a missing path, or a non-file is an input error; a size
or identity change during the read is an artifact-changed error; empty
input reports entropy 0; cancellation is honored before and during the
read. Summary detail retains the complete series and returns file
entropy, counts, and the ten longest runs for inspect_analysis_view,
while the registered effect remains read-only Evidence and the
diagnostics docs record the operation and its errors.
* fix(diagnostics): flag zero-size files as not shown empty
Generated files such as Linux /proc entries report size 0 while holding
content, so inspect_byte_entropy read nothing and returned an empty-looking
report. A file that reports size 0 now carries a limitation that the result
does not show the file is empty. The result stays a success because the
tool reads the declared size, which the file-stability checks depend on.
* fix(mcp): reject unsupported diagnostic summaries before inspection
* fix(ci): repair integrated checks and Hopper test baseline
* test(entropy): use shared MCP schema verification after merge
* fix(catalog): list inspect_byte_entropy under its own provider
Adding inspect_byte_entropy to BINARY_DIAGNOSTICS_TOOL_CONTRACTS put it
under pwntools-elf in the generated product catalog, because the
pwntools group took every binary diagnostics tool except
inspect_pe_resources. The service reports provider byte-entropy.
Add a BYTE_ENTROPY_PROVIDER identity beside PE_RESOURCES_PROVIDER, use
it in ByteEntropyService, give it its own catalog group, and name the
pwntools tools (inspect_binary_layout, inspect_recorded_crash)
explicitly so a new diagnostics tool is not attributed to pwntools by
default. The catalog test pins both groups.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KFTE4BHbGYzgf8Uhzcppdh
* fix(cli): resolve the byte-entropy path with absoluteCallerPath
main replaced the node:path resolve import in binaryDiagnosticsCommands.ts
with absoluteCallerPath (#4067), so the byte-entropy command's
resolve(args.path) no longer type-checks once the PR is merged with main.
Use absoluteCallerPath like the other commands, and add
src/filesystem/callerPath.ts matching main so the branch builds on its own.
* fix(diagnostics): retain entropy read cleanup ownership
* docs(diagnostics): explain entropy output capacity
* fix(diagnostics): preserve entropy cancellation outcomes
* fix(diagnostics): close the entropy input and warn on large reports
Public inspect_byte_entropy input now uses publicInputStrictObject before
detail is added, so unknown keys stay rejected on the advertised schema.
The tool description warns that complete output can become very large and
points callers to a shorter length or a larger block_size.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(diagnostics): keep byte-entropy registration mergeable with main
Register inspect_byte_entropy beside layout inspection and reject
unretained summaries before the file read, without editing workflows.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(diagnostics): register byte entropy with the shared tool options
Use toolRegistrationOptions so the handler typechecks on this branch and
on main, and still refuse unretained summaries before the file read.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
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: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
* feat(artifacts): make ASAR header admission configurable
ASAR header/index admission was a fixed 16 MiB with no override, so
operators with large Electron indexes could only extract the archive.
REA_ASAR_MAX_HEADER_BYTES now sets it (default 16777216, maximum
268435456). One owner resolves the effective admission for the
classification probe, inventory, ASAR reader and Electron file scope,
including the Electron header cache budget. Startup and doctor validate
the setting; admission refuses an invalid value instead of falling back.
Recovery and error details name the effective value and its source.
Fixes#6176
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(artifacts): resolve ASAR header admission from the caller's environment
The admission read process.env, so composition roots that select their own
environment (createDirectAnalysis, createServer, CLI, optional observation
factories) could not raise or lower it, and an ambient value leaked into
callers that left it unset.
Nothing reads process.env now. ArtifactProvider and extraction resolve the
admission from their environment; JavaScript analysis parses it from the
environment its server or CLI caller passes and refuses an invalid value;
the Electron and V8 providers receive it from their factories. Inventory,
nested ASAR readers, classification probes and Electron page authorization
carry that one value. A header cached by Electron under a larger admission
is refused for a smaller one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Select completed source-to-bundle mappings and candidates through the shared view owner, preserve reference-file provenance, and retain full Evidence. Reuse bounded JSON reading, heap admission, and cancellation before session writes.
Verified public Redux Toolkit source/map facts with an independent oracle, equivalent CLI/MCP workflows, focused negative controls, and complete CI/review. Historical paired SDK context estimates fall about 64%; timing/resource tradeoffs and final verification receipts are recorded without a general speedup or actual model-token claim.
Fixes#6112.
Add opt-in Frida session status summaries linked to complete retained Evidence. Share canonical session facts across contracts and preserve observed state, source identity and capture truncation.
Validated with native SDK/client workflows, default delivery compatibility, lifecycle and provenance tests. The completed large-history task uses 50.9% fewer estimated request tokens; no general CPU or latency improvement is claimed.
Fixes#5640
Add opt-in retained GDB and objdump summaries using the shared analysis-view layer. Preserve default complete Evidence, ordered records, provenance and completion facts.
Validate real Bash disassembly, whole-client context costs, CLI publication and cleanup; retain the original measured cohorts and explicit coverage limitations.
Closes#5584.
Teach client deadline recovery before REA results can be discarded, distinguish
producer-owned server budgets, and preserve Evidence/cleanup uncertainty.
Include actual Codex CLI recovery probes and CLI/MCP regression coverage.
Fixes#5598
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Retain native-only dispatch workflows without requiring a deep provider profile. Validate exact target, operation, and current reader bindings during open, import, recording, and export; preserve selected deep bindings and caller limits.
Validated public CLI and stdio MCP save/reopen, exact CLI replay, changed-limit cache partitioning, baseline failure and candidate success on an Apple-clang fixture, snapshot lifecycle regressions, typecheck and lint. No target or deep engine execution. Fixes#5529.
Add opt-in Go build summaries and selected retained metadata pages while preserving complete Evidence and source identity.
Validated with 258 focused tests, full static/docs checks, real CLI/SDK workflows and native metadata oracles. CI baseline remediation assertions reproduce on unmodified main; fail-fast cancels two other shards. Owner authorized bypass with those coverage limits recorded in PR #5524.
Fixes#5499.
Share asynchronous executable selection between discovery and execution. Recheck it for default Linux x64 sessions, preserve caller-injected service policy and propagate cancellation through pending probes.
Refs #5086. Focused owner, inventory and MCP controls passed; Linux-specific discovery and execution cases were skipped on Darwin arm64 and remain unverified.
Project large local Evidence captures through the authenticated file-source boundary and add guarded opt-in sibling-pair path inference. Preserve request cancellation, resource ownership and file-relative validation diagnostics.
Validated relevant source and compiled CLI/MCP/environment boundaries, static/build/docs/catalog gates, and a real isolated Gitea 28.2.0 capture through CLI, default stdio MCP and HTTP replay. Current-head automated review passed; unrelated long-running platform jobs may still be pending.
Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
* feat(il2cpp): inventory IL2CPP global-metadata images, types and methods
Add inspect_il2cpp_metadata (CLI inspect-il2cpp-metadata), a read-only
in-process decoder for unencrypted Unity global-metadata.dat version 39.
It reports header sections, serialized index widths, images, type
definitions (nesting from the nestedTypes section) and method names.
Unrecognized magic and other versions are unsupported; damaged headers,
overlapping sections, inconsistent record sizes, out-of-range indices and
invalid strings fail with a reason code and no partial success. MCP
detail summary retains the complete Evidence and pages rows through
inspect_analysis_view kind il2cpp-metadata.
Adds an opt-in verify:il2cpp:metadata -- --metadata PATH check.
* feat(il2cpp): deliver metadata summaries by default over MCP
A 112,232-method file produced a 10.5 MB complete response, above the
10 MiB stdio budget. Default MCP delivery is now the retained summary;
detail complete stays available, and the one-shot CLI requests it.
* fix(il2cpp): reject shifted strings, nesting cycles and method owner drift
Review fuzzing showed that moving the strings section offset by one byte
silently renamed every image, type and method. Name indices must now start
a string, which also bounds total decoding by the section size.
Nesting cycles and methods whose declaring type disagrees with the owning
type range are rejected instead of returned. Adds service, shutdown and
index-width coverage, and moves environment-specific measurements out of
the public guide and tool description.
* feat(il2cpp): decode global-metadata versions 29 and 31
Unity 2022.3 writes version 29 or 31 metadata: a 256-byte header of
(offset, size) pairs, fixed 4-byte indices, type records with
elementTypeIndex, and method records that gained returnParameterToken in
version 31. Record counts come from section sizes and must be whole.
Sections report a null count for these versions and index widths report
fixed-width-version. Image, type and method rows keep the same shape, and
the string, nesting and method-ownership checks apply to every version.
* fix(il2cpp): bound report size before serializing and tighten coverage
Rows share decoded names, so a 130 KB file could expand into gigabytes of
JSON before the 64 MiB budget check, ending in an internal RangeError. The
provider now refuses from a lower bound on the serialized rows first.
The decoder also rejects non-empty sections inside the header, methods
outside their declaring type's range and overlapping image type ranges, and
keeps a leading byte order mark in names. Layouts now carry one indexing
mode instead of two coupled flags, and the tool description explains
nested_type_start.
* fix(il2cpp): refuse oversized metadata before decoding rows
Address review findings on the IL2CPP metadata inventory:
- check a lower bound from header row counts before any row object is
allocated, so a large rejected file no longer builds every row first;
- validate sealed parent Evidence and count its rows once per report
instead of on every inspect_analysis_view page;
- decode version 39 fixtures with 2- and 4-byte type-definition,
generic-container and parameter indices.
* docs(il2cpp): attach the decoder comment to readIl2cppMetadata
* fix(il2cpp): deliver complete rows by default like the other inspection tools
inspect_il2cpp_metadata defaulted to detail summary, the only inspection
tool to do so. Omitted detail now returns every row inline, as
inspect_artifact, decode_interface_builder and the capture tools do;
summary stays one argument away and the guide, CLI reference and skill
reference say to select it first for large games, whose complete MCP
delivery is refused at the stdio budget with retained Evidence.
* test(il2cpp): cover narrow-width -1 sentinels and fix the skill's default
An empty image stores its type start as the all-ones value of a one- or
two-byte index; the decoder reads it as -1, but no fixture exercised it,
so removing either conversion passed the suite. The fixture can now append
an empty image, and both widths decode it. The skill still described a
summary default; it now says to select summary first, as the guide does.
* docs(il2cpp): request summary explicitly in the summary example
* chore(il2cpp): hash the verifier metadata through owned file resources
* fix(il2cpp): count escaped name length without building the escaped string
* fix(il2cpp): keep the verifier's check failure and small-table last page
* feat(domain): count JSON string length without building the escaped string
* fix(il2cpp): keep descriptor cleanup owners and share the JSON length count
* test(domain): give the backslash case real backslashes
* fix(il2cpp): select the CLI path and finish the command like the other tools
Follow main's absoluteCallerPath (#4067) and pass the command signal to finishAnalysisCommand.
* fix(il2cpp): select the verifier input path like the CLI
Use absoluteCallerPath (#4067) so a path with a symlink followed by .. names the same file the CLI and MCP inspect.
* feat(il2cpp): add compact composable metadata queries
Retain source-indexed Evidence for filtered batch and field queries. Bound representation growth before serialization, yield decoding for cancellation, and share CLI Evidence publication with desktop inspection. Verify public Unity metadata against independent byte and managed-DLL oracles and exercise actual stdio SDK workflows.
* fix(il2cpp): retain the validated metadata header magic
* test(il2cpp): remove obsolete execution wording exception
* fix(artifacts): preserve export selection and completed source facts
---------
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Serve retained capture Evidence as a bounded MCP replay environment with discovery.
Preserve default stdio, caller-selected facts and complete source Evidence.
Fix numeric fidelity, argument identity, startup cancellation and bounded discovery,
query/path matching and output metadata. Verify real recorded API data and public
CLI/MCP workflows; preserve explicit gaps for Windows and third-party hosts.
Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Adapt the prepared descriptor lifecycle repair from xu91102/rea dbb7db16. Bind exact file cleanup leases, retain typed physical failures and cancellation reasons, and join CLI/MCP finalization and active preflight. Share canonical Evidence construction and retain completed reports across reader handoff cancellation.
Scope active capture admission through shutdown and gate launch after close. Preserve successful descriptor peers and retry only unresolved owners. Separate process/transport retry ownership remains tracked in #4805.
Validation: 168 focused checks passed, one Windows-only skip; built CLI and actual stdio MCP controlled descriptor recovery; build, static and docs checks. No natural OS fault or real Electron launch/teardown claim. Ordinary full replies and Evidence IDs remain byte identical across 30 small CLI tasks.
Fixes#4658
Co-authored-by: hhang <169027046+xu91102@users.noreply.github.com>
Refs #4471, #3946.
Read only admitted regular descriptors without blocking on pipes. Retain failed closes, join discovery workers, and propagate cancellation through CLI and MCP. Preserve command and descriptor cleanup as independent owners.
Refs #4373, #4455, #4457, #4458.
Use canonical artifact ownership in Go, Rust, SQLite and PE readers and their failure consumers. Admit PE read budgets before allocation and ignore zero-extent sections in interval ownership. Close Rust resources through CLI and MCP lifecycles.
* fix(application): retain completed evidence through cancellation
Validate completed provider reports before classifying cancellation and preserve Evidence and captured diagnostics. Share MCP recording and delivery across custom observation handlers. Add source-owned completion and public SDK recording controls. Refs #3923, #3927, #4261.
* fix(wasm): retain final observations through cancellation
Keep completed Evidence after finalization and through CLI/MCP delivery. Preserve output and cleanup failure precedence. Refs #4254.
* fix(browser): retain final observations and forward cancellation
Classify final CDP detach and completed scenario cleanup at the provider boundary. Translate completed partials into canonical Evidence for MCP recording, and forward CLI cancellation to passive Electron tools. Refs #4255, #4256, #4257.
* fix(ghidra): isolate cancellation of shared startup waiters
Keep startup group-owned while each caller has an independent abortable wait. Await final-owner cleanup and preserve cleanup facts before retrying. Reuse the shared abortable promise helper. Refs #3983.
* fix(mcp): keep shutdown registrations until cleanup succeeds
Retain repeated event requests while unresolved owners need cleanup, and unregister only after success. Verify coalescing and failed-owner retry. Refs #4253.
* fix(adb): own transfer snapshots and stage screen publication
Bind transfer digests to the exact private input bytes and preserve caller APK names. Retain failed descriptors and private-root owners with typed cleanup evidence; publish captures exclusively after the cancellation cutoff. Refs #4251, #4252.
* fix(verification): report ADB cleanup failures
Always close after attempted verification and keep unexpected primary failures and cleanup details visible. Exercise the production script with controlled imports, including null and undefined throws. Refs #4260.
* fix(runner): stop owned Windows commands on cancellation
Use the retained ChildProcess handle for IPC cancellation and parent disconnection. Keep the SQLite lock until observed child close, and include native Windows regressions in the curated CI lane. Native Windows results remain pending. Refs #4258.
* fix(website): canonicalize link containment boundaries
Compare resolved targets with resolved repository and site roots. Accept directory aliases while preserving escape checks and keep fixtures within their temporary owner. Refs #4264.
* docs(testing): cover completion races and cleanup retry
Clarify validation-before-cancellation, independent startup waiter controls, producer and adapter coverage, and repeated shutdown events.
* fix(filesystem): retain file owners and completed reads after close failure
* fix(session): report retained snapshot staging in cleanup status
Fixes#4277. Include both snapshot and profile file-resource scopes in the owning status fact, preserving publication receipts and cleanup retry.
* docs(mcp): clarify recovery of raw partial observations
Document the observed SDK cancellation boundary and the open design decision in #4276 without promoting raw errors to Evidence.
* fix(kuna): own the complete installation inspection lifetime
* test(kuna): cover session cleanup of shared cache resources
* fix(hopper): isolate publisher operation resource admission
* fix(hopper): preserve launcher cleanup failure classification
* fix(adb): retain ordered cleanup and screen publication outcomes
* fix(runner): retain Windows job ownership through cleanup retries
* docs: clarify inspection admission and ordered cleanup regressions
* fix(ghidra): preserve startup cleanup and request deadlines
* fix(runner): supervise stdin errors and bootstrap native controls
* docs: require queued lifecycle controls to survive admission
* fix(cli): leave cleanup resolution with resource owners
* test(adb): verify owned install snapshots through CLI
* fix(errors): exclude resolved primary cleanup resources
* fix(adb): resolve publication cleanup after its handle closes
* fix(android): resolve JADX hash cleanup after owned close
* refactor(android): share hash failure cause options
* fix(kuna): gate commands on retained descriptor cleanup
* docs: cover cleanup admission and owner-confirmed recovery
* refactor(artifacts): bind cleanup errors to confirmed release
* fix(adb): resolve recovered cleanup at retained owners
* fix(kuna): resolve installation cleanup after owned close
* fix(kuna): gate cache reads on retained hash cleanup
* fix(setup): preserve publisher cleanup admission failures
* fix(android): resolve the reported retirement cleanup error
* test(runner): scope post-spawn fault control to POSIX
* test(adb): cover persistent snapshot owner retirement
* fix(kuna): preserve file outcomes with explicit cleanup ownership
* fix(artifacts): resolve errors through retained cleanup owners
* docs(lifecycle): carry cleanup ownership in typed outcomes
* fix(adb): bind staged screen errors to their cleanup lease
* fix(kuna): bind profile cleanup through a close capability
* fix(artifacts): retain descriptor resources in cleanup errors
* fix(pcap): bind existing errors to snapshot retirement
* fix(windows): load source owner through its file URL
* test(build): copy the command runner helper into fixtures
* fix(mcp): own shared observation providers in the transport
* fix(jadx): resolve every retained cleanup retry error
* fix(kuna): bind retry errors to every retained cleanup owner
* fix(adb): bind admission and shutdown errors to exact cleanup leases
* fix(windows): resolve command paths before native ownership
* test(publisher): assert exact descriptor recovery without release metadata
* docs(lifecycle): require every retry error to follow its owners
* fix(kuna): keep hash cleanup state stable across concurrent retries
* test(windows): exercise surviving descendants with scoped shutdown deadlines
* fix(uninstall): preserve primary read errors through cleanup failure
* test(publisher): assert cleanup Result and exact owner recovery
* test(windows): observe supervisor resources through IPC disconnect
* fix(browser): retain typed cancellation after interrupted actions
* test(publisher): assert ownership phases without retry-count coupling
* fix(lifecycle): preserve abort reasons through shared provider execution
* fix(jadx): preserve execution and late hash cancellation causes
* fix(adb): compose late cancellation with exact cleanup failures
* test(mcp): use the shared budget for session workflows
Own CDP transports from admission through observed close, retain failed
owners for retry, and keep active peers separate from pending cleanup.
Preserve primary errors and completed facts through final cancellation.
Forward passive Electron CLI cancellation and dispose browser, runtime and
scenario owners from CLI and MCP shutdown.
Refs #4255, #4256, #4257
Probe the selected clients through their owning providers and expose current host availability through binary_session. Keep device/serial and target applicability separate. Reject unrecognized successful version output; retain the bounded producer output and original version spelling. Apply the documented Apktool floor, including the verified Debian dirty build.
Validation: provider/version tests and public MCP grouped availability; no real Android device or APK provider verification claimed.
Fixes#3067Fixes#3068
Related: #3077
Co-authored-by: Taksh <takshkothari09@gmail.com>
Capture the current entrypoint once without inventing a path. Preserve unknown registration ownership through setup and doctor, refuse unsafe registration plans, and retain exact pinned-launcher readiness checks. Hash the same full or compact schema projection advertised by each MCP server and use that identity in doctor comparisons.
BREAKING CHANGE: server.command_path may be null when the invocation path is unavailable. Registration and setup statuses, and doctor classifications, may report unknown.
Reviewed-PR: #3230, #3015
Co-authored-by: qorvr <330186599+qorvr@users.noreply.github.com>
Co-authored-by: Hemang Varshney <218273197+hemv-857@users.noreply.github.com>
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.