Preserve XML, OpenStep and binary dictionary keys at their format owners. Share validated binary reference facts with materialization while retaining scalar precision, UID identity and bounded expansion. Migrate archive, Interface Builder, native and app-bundle consumers, then remove obsolete key-omission accounting and schema copies.
Validated source regressions and compiled CLI/MCP workflows, including native plist fidelity and archive identity. Typecheck, lint, docs and test discovery pass. No performance benchmarks were required.
Retain validated DOS relocation records in their domain owner and consume
those facts in Ghidra load-image preparation. Preserve ordered duplicate
aliases, overlapping writes, and original/final byte evidence.
Share FAT header facts across generic, native, and Hopper readers without
merging their distinct admission policies. Replace managed method bodies'
two identical mapping lookups with one owned offset-and-extent result.
Validation: 660 focused tests passed across 19 suites; typecheck, lint, and
test discovery passed. Hopper/Ghidra checks used fixtures and simulated
provider observations; no real external provider execution was performed.
Share ELF note headers across note inspection, Flutter build IDs, Node SEA,
and recorded-crash source binding. Decode REL/RELA records once for MIPS
shared-load analysis and IL2CPP linking, removing superseded scalar helpers.
Share the CLR header prefix between desktop detection and managed PE parsing
while preserving their distinct read bounds and admission policies. Cover
those differences and ignored R_NONE fields with production-boundary tests.
Validation: 493 focused tests passed, two existing skips; static checks and
test discovery passed. Public managed/desktop CLI and ELF notes CLI/MCP
workflows exercised; no real external analysis providers were run.
Reuse the existing provider input admission helper across twelve services,
preserving cancellation, schema errors, path policies, and Evidence handling.
Share ELF dynamic records across Dart, MIPS, and IL2CPP readers, and reuse
Mach-O segment and section records for Node SEA location.
Require canonical DOS ownership before GPU PE section discovery so relocation
bytes cannot masquerade as a PE pointer. Cover valid short DOS headers and
the malformed case through both inventory and the public CLI.
Centralize ELF section and Godot trailer declarations while preserving caller admission policies. Route six PE entrypoints through canonical DOS ownership so relocation data cannot establish a PE header, and update NativeAOT interpretation identity and verifier dependency coverage.
Share exact ELF program-header facts across nine consumers while preserving their admission and precision policies. Centralize conformance path and digest binding, retain verifier-specific checks, and route fixture-owner changes to CI qualification.
When cancellation or the deadline interrupted LLDB after it had published
its bridge result, the tracer never read that result, so an explicit
`target_process_created: false` (or `target_process_exit_observed: true`)
was lost. The run kept a `native-target:unknown` marker that no cleanup
retry could release, wedging the tracer for every later trace.
Read the published result once LLDB's process group is stopped, even for
an interrupted run, and apply the same target-gone proof in cleanup retry.
Cancellation or timeout stays the primary outcome; a created target, a
truncated result, or a missing PID alone stays unresolved.
Fixes#5385
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
inspect_macho reported only the symbol-table spelling (`_main`), while
LLDB, dlsym and observe_native_calls use the runtime spelling (`main`).
Passing a static name as a breakpoint silently selected a different
function, so results from the two tools could not be joined by name.
Keep `name` as the exact symbol-table fact and add a derived
`runtime_name` to every export and import row, produced by one shared
Mach-O symbol-name owner. Managed P/Invoke verification now uses the
same owner instead of its own underscore stripping.
Fixes#5298
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Apple's crash report JSON documents termination.byPid, byProc and flags, the body's parentPid, and
the metadata line's build_version and platform. The parser shapes did not list them, so they were
reported only by name in unlisted_keys / unlisted_body_keys and their values were dropped: a
watchdog kill no longer said which process ended it, and process kept parentProc without its pid.
#4297 asks for termination members beyond namespace/code/indicator to be retained as recorded, and
docs/apple-ips.md says documented fields are reproduced.
They are now kept: termination.by_proc, termination.by_pid and termination.flags, process.parent_pid
and metadata.build_version / metadata.platform. The integers are recorded integers, so they count
toward max_integer_text_bytes and a type mismatch is recorded like the other fields.
* feat: add FreeBuff agent support for REA setup
Register FreeBuff as a supported setup client using the shared user
agents directory (~/.agents/mcp.json with mcpServers, skills in
~/.agents/skills), which matches what FreeBuff Desktop loads. Adds the
client definition, boundary tests, supported-agent docs, and the skill
reference client list.
* fix(freebuff): detect FreeBuff from its profile directory, not shared .agents
The ~/.agents marker made FreeBuff appear installed for any home where
REA had installed shared skills (the default skill destination, also
Gemini CLI's), producing false doctor failures. Detect FreeBuff from
its own fixed profile directory ~/.config/freebuff-desktop instead,
and add a regression test covering a home with only the shared agents
skill directory.
* fix(setup): require product evidence for FreeBuff discovery
Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request.
* fix(uninstall): retain unverified shared client configuration
* fix(clients): preserve scoped removal evidence
* fix(doctor): omit undefined selectedClientIds under exactOptionalPropertyTypes
Passing selectedClientIds explicitly as undefined fails typecheck on this
branch (TS2379), which blocks the focused test workflow before any test
can run. Spread the option only when defined.
* fix(update): separate ownership evidence from product applicability
rea update's maintenance scope inspected only product applicability
evidence, so when a FreeBuff profile was absent but REA already owned a
version-pinned row in the shared ~/.agents/mcp.json, the plan omitted
freebuff and left the integration stale. FreeBuff now declares its
registration storage as shared, which proves ownership of an owned row
but never product applicability, and maintenance requests ownership
evidence through that declaration instead of reinterpreting the shared
paths. Doctor and setup keep readiness evidence, foreign rows stay out
of maintenance, and the Doctor exactOptionalPropertyTypes fix makes the
focused test workflow runnable.
* test(dotnet): split oversized operand extent diagnostics describe
The describe callback reached 162 lines (max 150), failing
max-lines-per-function and blocking the pre-push check for this branch.
Move the single-case extent scenarios into their own describe; no test
content or order changes.
* fix(update): preserve ZCode's disabled shared registration during maintenance
The shared user agents file doubles as ZCode's fallback, where
`enable: false` disables the registration. Ownership-based maintenance
read that row as a FreeBuff registration, whose format does not
recognize the flag, so the row was selected and the emitted setup
command rewrote it, dropping the flag and silently re-enabling a
registration the user had disabled.
registrationActivation now honors `enable: false` for any client whose
registration storage is shared, because the activation fact binds every
reader of that storage. Maintenance leaves such rows out; doctor
reports them as stale, matching ZCode's own treatment.
* fix(doctor): let explicit client selection authorize the config read
When an ACL or an inaccessible shared parent made every access probe
fail, a client selected by name was omitted before the configuration
read could return its unreadable-config detail, so doctor reported it
as not detected with installation remediation: an unresolved selected
path collapsed to absence.
An explicit selection now authorizes the read outright and the probes
serve automatic discovery only. A selected client with an unreadable
config reports invalid with the read failure; one with no config
reports missing; automatic discovery still probes before inspecting.
* fix(uninstall): share shared-storage checks between ZCode and FreeBuff
clients() queued ~/.agents/mcp.json twice: once as zcode_fallback and once
as freebuff. ZCode has no discoveryPaths, so its strict read still blocked
uninstall on malformed shared text, despite FreeBuff's new retain-and-continue
behavior. For a valid owned entry, ZCode removed it first, so FreeBuff reported
skipped rather than removed.
Make the shared file's checks and removal one shared decision:
- Add zcodeDiscoveryPaths to ZCode so it has its own applicability evidence.
- Gate zcode_fallback push on applicable, not just zcodeFallbackPath presence.
- Report shared storage ownership as one decision for both clients:
FreeBuff and ZCode now use clientOwnershipEvidencePaths together, so a
recognizable REA-owned row proves ownership once for the shared storage, and
both clients report the same result consistently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(uninstall): merge duplicated host and prove shared ownership from owned rows
Uninstall.ts declared systemUninstallHost twice, preventing module load,
with the exported copy returning only clients and the second copy missing
clientWriteBlocker. Merge into one exported host carrying both blockers.
hasOwnershipEvidence used access() existence, so an unrelated malformed
~/.agents/mcp.json established ownership and blocked every removal.
Ownership now requires a readable, recognizable REA-owned row via the
injected filesystem, so unrelated shared data stays retained.
Also cover ZCode discoveryPaths in its path test.
* fix(uninstall): keep denied product-local configurations fail-closed
Unproven product applicability marked every configuration path of that client unverified, so a denied ZCode profile turned an unreadable product-local config into a retained item: uninstall continued and could report complete with REA still registered. The retain-and-continue exception now applies only to storage REA does not own, classified once by clientSharedRegistrationPaths (shared configuration plus another product's same-scope fallback).
Covers the Greptile P1 on Uninstall.ts. Validation: the new test fails on the pre-fix Uninstall and passes after it; freebuff/zcode/updateMaintenance/bom/dsh suites green; clientLifecycle, clientRegistrationStatus and claudeDesktop keep the same 8 host failures as the pre-merge baseline (symlink EPERM, stale-vs-aligned on Windows).
* fix(update): retain FreeBuff when ZCode reads the shared fallback
Maintenance deduplicated clients on the path each inspection read, so ZCode's fallback view of ~/.agents/mcp.json marked that file "covered" and dropped FreeBuff from the scope. ZCode setup writes ~/.zcode/cli/config.json and deliberately leaves the fallback untouched (docs/client-configuration.md), so the emitted command refreshed only ZCode while the shared row both products load stayed pinned to the old package version. Each setup action rewrites only its own configuration path and no other action rewrites the shared row, so every selected client keeps its own maintenance action; the read-path covered/deduped filter is removed.
Covers the Codex P2 on UpdateMaintenance.ts:104. Validation: the new regression fails on e2fdec384 with {clients:["zcode"]} and passes with {clients:["freebuff","zcode"]}; updateMaintenance 31/31, setupClientConfigCleanupOwnership, cliUpdateAlias, updateOutput, cliStartupImports green; tsc --noEmit, oxlint (0 errors) and oxfmt --check clean; clientRegistrationStatus keeps the same 4 symlink/stale-vs-aligned failures this Windows host has on base e2fdec384 (verified by stashing the change).
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): preserve completed reads as shared ownership evidence
hasOwnershipEvidence caught every read failure and kept scanning, so a handle-close failure after a successful read — a RegularFileCleanupFailure whose completed outcome still contains the exact shared-file text — was discarded as "no proof". FreeBuff's applicability-unverified storage therefore never got its ownership fact, and once the retained handle blocked later reads, readClientConfiguration downgraded them to retained: inspection passed, removals soft-failed, and runUninstall(true) could purge REA data while the active shared registration remained. The catch now parses the completed outcome for the ownership text while missing or unreadable storage and malformed data keep their proves-nothing semantics, so ownership holds and every later read failure stays blocking.
Covers the Codex P2 on Uninstall.ts:252. Validation: the new regression fails on 4dbfdf1a9 (freebuff reports no blocking failure while the poisoned-scope error lands on claude_code) and passes after; setupClientConfigCleanupOwnership 25/25; the other 21 Uninstall-consumer suites are byte-identical to base 4dbfdf1a9 (61 pre-existing Windows-host failures: symlink EPERM, stale-vs-aligned); tsc --noEmit, oxlint (0 errors, same 6 warnings) and oxfmt --check clean.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): keep owned-row proof through removal refusals
hasOwnershipEvidence treated any clientRegistrationRemoval refusal as no ownership: an effective REA-owned rea member shadowed by an earlier foreign duplicate (shadowed_unowned_member), or an owned native row beside a foreign V1 fallback (foreign_legacy_fallback), discarded the already-parsed positive row fact. With FreeBuff unverified and close failures recurring on the preflight/removal rereads, those failures were then downgraded to retained, so runUninstall(true) removed the skill and purged REA data while the active owned row remained. The refusal now carries the owned rows that motivated it — the refusal only refuses the edit — and hasOwnershipEvidence evaluates that fact on both paths; preflight and removal keep refusing the unsafe edit exactly as before.
Covers the Codex P2 on Uninstall.ts:269. Validation: the new regression fails on 225cb214a (freebuff reports no blocking failure while the poisoned-scope error lands on claude_code) and passes after; setupClientConfigCleanupOwnership 26/26; the 21 Uninstall-consumer suites are byte-identical to the recorded 225cb214a baseline (61 pre-existing Windows-host failures: symlink EPERM, stale-vs-aligned); tsc --noEmit, oxlint (0 errors, same 6 warnings) and oxfmt --check clean.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): keep unresolved discovery probes from softening shared failures
The discovery probe swallowed every stat failure, so a FreeBuff profile denied with EACCES/EIO was indistinguishable from an absent profile: shared storage was marked applicability-unverified and, when ~/.agents/mcp.json also remained unreadable, the ownership and removal reads softened to retained. runUninstall(true) then removed the skill and purged REA data while an installed FreeBuff could still hold an active registration — the regression even reports complete. Absence (ENOENT) is now the only state that leaves shared paths unverified; any other probe failure leaves applicability unresolved, and shared-config failures stay blocking.
Covers the Codex P2 on Uninstall.ts:318. Validation: the new regression fails on 7572a7082 with status complete and purged data and passes after; freebuffClientConfiguration 13/13; the Uninstall-consumer batches are byte-identical to the recorded baselines (61 pre-existing Windows-host failures: symlink EPERM, stale-vs-aligned); tsc --noEmit, oxlint (0 errors, same warning rules) and oxfmt --check clean.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): retain completed configuration reads as removal evidence
A close failure after a completed read discarded the text that read
produced, so an owned registration row the text proves softened to
retained. The completed text now drives removal, keeping shared-config
failures blocking when ownership evidence exists.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(uninstall): stop removal when a cleanup retry leaves a handle unreleased
A completed reread whose handle the cleanup retry cannot release now fails
blockingly instead of serving the text: with no owned row, the soft path
let removeAll purge managed data before close() reported the incomplete
cleanup. The completed text is served only after the retry releases the
handle; an unreleased handle is REA's own failure, never applicability
uncertainty, so it bypasses the retained softening.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(uninstall): keep the ZCode fallback when its profile probe is unresolved
A denied or failed profile probe leaves ZCode's applicability unresolved,
never absent, but the fallback branch dropped the shared row on
applicability alone: with the native config and FreeBuff's profile both
absent, an installed ZCode kept its uninspected registration while
uninstall purged skill and data. Unresolved probes now keep the fallback
in scope with the same fail-closed treatment as other unresolved shared
paths; definitive absence still keeps ZCode out of another product's
primary storage.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(setup): preserve a shared row's enable:false during FreeBuff repair
The shared agents file doubles as ZCode's fallback, so its `enable: false`
binds every reader: doctor now reports the disabled row as stale for
FreeBuff, but following that remediation rebuilt the generic JSON entry
without the flag and silently re-enabled a registration ZCode disabled.
Repairs of shared storage now carry the activation fact forward, while a
client's own native storage keeps its established single-reader repair
contract; the denied-profile uninstall regression also pins the
fallback's new fail-closed inspection beside the denied read.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* test(uninstall): retarget the completed-reread regression to a released retry
The concurrent-writer regression held the reread handle open forever,
which the fail-closed path now serves: it duplicated the unreleased-handle
regression while documenting the opposite contract. The fixture's close
spy gains a failure limit so the cleanup retry releases the handle, and
the test again proves the completed text drives removal of the
concurrently added owned row, with purge verified against the cache
layout purge actually removes.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(doctor): report a preserved shared disable as a manual conflict
Preserving a shared row's enable:false left doctor recommending a setup
run that registrationCurrent correctly treats as already current, so the
scoped doctor returned needs_human forever. The shared-enable
interpretation now has one owner, sharedEnableFlagBinds, used by both
the activation rule and the remediation: a row disabled through the
shared flag reports the manual conflict and states that rea setup will
not change it, instead of an endlessly ineffective repair.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(doctor): keep a native ZCode disable on the setup repair path
The manual-conflict remediation matched a native zcode row through
sharedEnableFlagBinds, but setup drops enable:false on single-reader
storage, so a native disabled registration was told setup would not
change it. The remediation now reads setup's own writer rule,
exported as setupPreservesDisabledActivation: shared storage and the
zcode fallback view keep the manual-conflict message, while a native
row keeps the working rea setup instruction. Regressions pin both
remediations.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* revert: drop the unrelated managed-CIL describe split
The split does not belong to FreeBuff client support and only widens this
PR's diff.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): remove the shared agent registration once for both clients
ZCode's ~/.agents/mcp.json fallback and FreeBuff's own configuration queued the
same physical file twice, so ZCode removed the row and FreeBuff then reported
it absent, losing the outcome for the client that owns the file.
Resolve every configuration path to one owner -- the client whose
configuration it is -- and project that single inspection and removal to each
client that loads it. A fallback reader still contributes its discovery probe,
so an installed or unresolved reader keeps the shared file fail-closed.
Discovery also accepted a dangling ~/.config/freebuff-desktop link, which setup
and doctor reject because they follow the target, so an unrelated malformed
shared file blocked every other removal. Resolve the link before treating the
profile as installation evidence, keeping lstat for removal safety.
Also date the FreeBuff release wording against the published 6.7.0 package.
* fix(uninstall): keep a row per client when two clients own one file
OPENCODE_CONFIG can point OpenCode at FreeBuff's configuration file, where
OpenCode writes `mcp.rea` and FreeBuff writes `mcpServers.rea`. Grouping by
filename gave that path a single owner, so uninstall removed only OpenCode's
row, reported that removal for FreeBuff, and could purge managed data with
FreeBuff's registration still active.
Share the decision only through a fallback view of another client's row: every
client that declares the path as its own configuration keeps its own
inspection and removal, and the fallback reader reports each of them.
* fix(clients): preserve discovery and fallback registration identity
Follow product discovery link targets without losing configuration entry
presence or explicitly selected inspections. Associate fallback readers with
the format owner's registration table and project outcomes by owner and path,
so OpenCode removal cannot be reported as a ZCode fallback removal.
All three new boundary regressions fail against the previous source and pass
with the fixes. Validation: check:fast; 217 focused tests passed; the two
changed test files were rerun with 50 passing tests. No installed FreeBuff
client was launched.
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Codebuff <noreply@codebuff.com>
* fix(apple): keep the recorded image name and frame symbol offset of IPS reports
Apple's IPS format documents usedImages[].name and frames[].symbolLocation, and docs/apple-ips.md says documented body fields are reproduced, but the parser shapes did not list either member. They were syntax-checked and discarded without an unlisted_keys entry, so a symbolicated frame lost its +offset and every image its binary name. Both are now kept: images[].name and frames[].symbol_location as a recorded integer, with type mismatches recorded like other fields.
* fix(apple): count frame symbol offsets in the integer text check
Use the domain-owned activity extra count in CLI parsing and advertisement. Preserve nested Rosetta registers at the selecting parser and qualified register projection, sharing the existing aggregate budget.
Port the Rosetta work from Adolanium commits 1889ac153 and c9e93bd88 in #6976, including morluto follow-up 07fa932ee. Add malformed-container and mixed-thread budget controls. CLI/MCP coverage uses a recorded ReportCrash excerpt in an authored report, without generating a native crash or contacting an Android device.
Refs: #6291, #6976, #6977
Co-authored-by: Adolanium <94890352+Adolanium@users.noreply.github.com>
Decode optional-header declarations once and pass detached directory words, locations and SizeOfHeaders to native consumers. Preserve executable machine admission, raw GPU/resource machine reporting, RVA mapping and certificate file-offset semantics.
Validation: fresh build/catalog, full static checks, 466 core/provider fixture tests, 122 workflow tests and 14 selected file-backed PE admission tests passed. Public CLI and actual stdio MCP used authored artifacts; installed external providers were not qualified. Added 17 structural cases and two GPU machine-policy controls. Eager directory decoding costs remain unmeasured.
Return the validated descriptor and its original metadata from regular-file
admission. Propagate that contract through owned reads, hashes, snapshots,
artifact inventory and provider file workflows instead of replacing initial
facts with another stat. Keep arbitrary output-handle operations separate.
Preserve final descriptor/path identity proofs, borrowed-source verification,
BigInt precision, cancellation provenance and failed-close ownership. Remove
the obsolete source and owned-ZIP baseline stages and update their consumers
and regressions. Tie read completion faults to actual reads instead of the
retired duplicate stat; instrument real handles without fake handle wrappers.
Validation: fresh runtime/catalog build; focused source, lifecycle, filesystem,
CLI/MCP and authored provider-fixture tests; full static checks; docs checks;
test discovery; duplication check. Platform-specific cases remain skipped on
macOS. No installed provider or device behavior was verified.
The IPS JSON reader decodes \uXXXX escapes with String.fromCharCode and
returns raw slices verbatim, so an escaped unpaired surrogate reaches
Evidence as-is: malformed text reported under complete coverage, with no
refusal and no uncertainty. A crash report's procName or exception message
comes from the crashed process, so the escape is reachable input.
Refuse the string the way the parser already refuses other malformed
content. The check runs on the decoded value, so it covers escaped and
unescaped text alike, and a high surrogate followed by its low surrogate
escape stays valid text.
Validation: RED then green in src/native/apple/losslessJson.test.ts, where
the new case previously accepted the escaped surrogate; 311 tests across
the apple parser suites pass; tsc --noEmit over the changed set exits 0;
oxlint reports 0 errors; oxfmt --check is clean; verify:module-boundaries
passes.
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Keep observed empty JSON strings separate from missing fields in IPS process,
image, frame, register and OS-version facts. Preserve empty unlisted keys,
retain malformed UUID source text, and keep unknown architecture interpretation
separate from raw spelling. Classification excludes empty supporting fields.
Validate producer cases plus compiled CLI and stdio MCP delivery against the
same output contract. This is saved-report inspection, without target execution.
Specialize the buffer-backed directory driver for its actual ELF consumers and remove the unused PE branch. Share PE subject architecture interpretation at the existing machine owner, preserving unknowns for conflicting formats and unproven managed overrides.
Validation: runtime build and 108 focused service, native parser, GPU, and CLI/MCP tests passed using local fixtures. Live descriptor-backed PE readers remain supported.
* feat(artifacts): inventory and extract Node.js single executable application blobs
Adds a node-sea artifact reader that locates the NODE_SEA_BLOB payload in
Mach-O sections, ELF notes and PE RCDATA resources, decodes the blob
header, main script, optional snapshot and code cache, and named assets,
and extracts their stored bytes through the existing safe output tree.
The executable is never run. Resource-tree errors in a PE without a
NODE_SEA_BLOB name stay with native classification; truncated, unknown
or over-limit SEA declarations fail closed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe
* fix(artifacts): reuse PE resource facts and bound SEA asset tables
Move the bounded NODE_SEA_BLOB name probe into the shared PE resource
layout module so SEA admission uses the same header and section mapping
as the full parser; the layout reader now accepts a header prefix with
the file size. Bound SEA asset count and decoded name bytes before
records are created and report resource bounds as limit failures. Offer
the JavaScript next probe only for main scripts with a source suffix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe
* fix(artifacts): make SEA metadata construction cancellable
---------
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: morluto <76467478+morluto@users.noreply.github.com>
* fix(targets): keep original DOS padding out of e_lfanew
A complete DOS header with a nonempty relocation table that ended before
e_lfanew treated the padding dword at 0x3c as a Windows declaration. Without
a recognized Windows signature, fall back to the validated DOS structure so
original DOS images are not refused as malformed Windows targets. Preserve
unresolved-candidate handling when no relocation table delimits the padding.
* test(ghidra): cover DOS padding and unresolved header candidates
* fix(targets): read Windows signatures before dismissing DOS padding
* docs(targets): reconcile DOS padding admission contract
Document that relocation-table padding inside a complete DOS header is DOS data, while an unread Windows signature beyond the current probe is requested before that rule applies.
Aligns docs/installation.md with docs/ghidra-dos.md after the MZ admission fix.
---------
Co-authored-by: dhruvac29 <dhruvac29@users.noreply.github.com>
Explain unreadable ELF note section names without discarding complete note coverage. Keep export and PE import rows when only version or DLL-name metadata is unresolved, and stop claiming those retained rows were unreported.
Use native byte equality for the 4 MiB ELF extended-numbering source-preservation checks; generic deep equality enumerated every buffer byte and exhausted the test worker heap. The full fixture and byte coverage remain.
Validation: focused ELF note, native export, and PE import regressions plus complete CLI/MCP adapter files passed under the existing 512 MiB heap limit. Build, typecheck/lint, formatting, and documentation checks passed.
Forward the file owner's completed stable-read hash and byte count through descriptor-close failure or cancellation in PE resources, certificates and imports, ELF notes and kernel modules, native exports, Apple IPS, and APK signature inspection. Preserve the primary failure, exact cancellation reason, and failed-close cleanup lease.
Validation: 32 acquisition-finalization regressions across eight providers and 30 existing APK provider, lifecycle, and identity tests passed. Existing native filesystem regressions and typecheck/lint also passed. No external analysis engines or Android device were used.
Keep malformed canonical devicetree phandles unresolved instead of falling back to legacy identities. Report the PE dynamic relocation offset and section at their exact source widths with Size-gated absence and zero preservation. Clarify classic kernel-module version coverage and byte-preserving string encoding.
Validation: 158 focused parser, service, filesystem, and finalization regressions; 14 CLI/MCP tests; build, typecheck/lint, formatting, and docs checks passed. Fixtures establish parser behavior; no external analysis engines were exercised.
* feat(elf): inspect Linux kernel module metadata
Adds inspect-kernel-module and inspect_kernel_module for ELF32/ELF64
ET_REL Linux kernel modules, read statically without executing them.
Reports ordered .modinfo entries with duplicates preserved, __versions
symbol CRCs, the presence of .gnu.linkonce.this_module and __ksymtab,
.init.text and .exit.text sizes, and an appended module signature
trailer with its PKCS#7 byte range and SHA-256. gzip, xz and zstd
containers are reported unsupported with external decompression as the
next probe. Malformed headers and exhausted entry budgets return no
partial success.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe
* fix(elf): bound kernel module ksymtab listing and tighten contracts
Charge listed __ksymtab* sections against max_entries, omit section names
longer than 256 bytes with ksymtab_name_exceeds_limit, and aggregate the
non-file-backed limitation so repeated huge names cannot inflate Evidence.
Use fixedTupleSchema for the signature pad bytes with projection parity
tests, and assert the late-cancellation reason and retained observation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe
* fix: resolve merge integration errors
---------
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: morluto <76467478+morluto@users.noreply.github.com>
* feat(pe): inspect TLS callbacks and load configuration
Adds inspect-pe-load-config and inspect_pe_load_config for PE32 and
PE32+ images, with artifact hashes and file ranges in the returned
evidence. Reports callback addresses and mappings, plus size-covered
security-cookie, SafeSEH, CFG, EH-continuation and XFG fields;
flag-derived mitigation claims are explicitly labeled inferred. Missing
directories remain null, and malformed storage or exhausted read budgets
return errors without partial success. Adds documentation and tests for
service validation, CLI/MCP access, malformed inputs and stable-file
handling.
x86 images that declare the legacy 64-byte load-config directory are
read to the structure's own Size when those bytes are file-backed, as
the Windows loader does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe
* fix(pe): retain snapshot facts and bound load-config section lookup
Keep the completed stable-read path, SHA-256 and byte count as a
file-snapshot-hash partial observation when descriptor close fails or is
cancelled. Report the checked Size span as structure_location and add it
to Evidence locations beside the declared directory range. Resolve
callback sections through a sorted segment index built once per image,
keeping the ambiguity failure. Pin every load-config field to offsets
transcribed from the PE/COFF spec and llvm COFF.h at its exact Size
boundary for PE32 and PE32+.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* 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>
* test(native): expect artifact_changed when a bound metadata target is lost
41e10b240 made a bound metadata target that fails the source boundary
(`path`) or disappears (`ENOENT`) report AnalysisArtifactChangedError, as
its comment and docs/testing.md state, but left the module test expecting
AnalysisInputError. The test now asserts the shipped contract, so main's
Test shard and Portable tests lanes pass again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(package): ship the CLI process environment owner in launcher fixtures
c2caae88f moved launcher environment preparation into
scripts/lib/cli-process-environment.mjs, made scripts/rea.mjs import it and
made verifyPackagePack require it in the packed listing, and updated the
dispatcher fixtures, but two other fixtures still omit it:
- packageTarListing's fake tar listing, so every case stops at "package
omitted the CLI process environment owner" before its own assertion;
- deferredRuntime's copied compiled package, so the copied launcher fails
to resolve its import instead of reporting the corrupted catalog.
Both fixtures now include the module, as the package ships it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(native): expect XML plist validation in typed-value provenance
9f5dd56e2 records a successful `plutil -lint` of an XML plist source in
provenance, as docs/native-investigation.md states, but the macOS typed-value
CLI test still expected only the `file` step for both formats. XML sources now
expect the lint step; binary sources are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>