* fix(targets): select a preferred Mach-O host subtype
Host admission refused every extra slice of the host CPU type, so arm64
plus arm64e and arm64e ABI variants never became universal targets. Rank
known subtypes and keep the earliest capability variant. Identical
subtypes and ties between unlisted bases still fail closed.
* fix(artifacts): treat a one-sided declared digest as metadata
An all-zero Godot MD5 was visible only because limitation text differed.
After comparison stopped using that prose, a claim on one side and no
claim on the other lost its metadata dimension. Compare the structured
integrity claim instead.
* fix(browser): keep unavailable resource inventories unknown
Directional coverage treated a resource retained from an invalid protocol
tree as an addition against a complete peer. An unavailable collection is
not a truncated sample, so it cannot prove membership.
* fix(native): read the admitted Mach-O slice for metadata
Capability-variant admission chose the first slice, then dispatch
metadata and slice tools ranked the FAT file again and rejected that
pair. Pass the admitted offset, and refuse a winner set that repeats
a subtype.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* feat(native): list ELF and Mach-O initializer and finalizer functions
inspect_native_initializers and inspect-native-initializers list the
functions an ELF or Mach-O image runs before and after main: ELF
DT_INIT, DT_FINI, preinit, init and fini arrays and .ctors/.dtors, and
Mach-O __mod_init_func, __mod_term_func and __init_offsets, with slot
addresses, resolved targets, symbols where available and relocation
facts for relocatable objects. Nothing is executed. Slot, symbol,
relocation and note budgets are shared across tables, sentinels are
matched at the image width, and target-derived names are bounded and
marked untrusted.
* fix(native): keep ELF initializer slots unresolved when relocation coverage is partial
A skipped, unreadable or over-budget section relocation table now keeps
every slot it could reach unresolved instead of reading the stored word as
raw or dropping a .ctors slot as a sentinel. Dynamic writes that only
partly overlap a slot, or write it twice, leave it unresolved. Linked
images no longer reapply retained non-SHF_ALLOC link-time records.
The dynamic relocation walk now pauses at the shared reader's step
boundaries and observes cancellation there, resolved targets need only
their first byte mapped, and unreadable symbol names make the report
incomplete.
* fix(native): stop reporting unchecked Mach-O initializer words as resolved
Object files now apply their own section relocations: an UNSIGNED entry
against a defined symbol gives symbol_addend, one against an undefined
symbol gives unresolved_import, and any other entry leaves the slot
unresolved. Linked images without a fixup decoder, such as 32-bit ones,
keep pointer slots unresolved when an LC_DYLD_INFO bind stream or
LC_DYSYMTAB external relocations could replace the stored word.
LC_DYLD_INFO rebases now report dyld_info_rebase instead of
chained_fixup, and unreadable symbol names make the report incomplete.
Section headers keep their declared reloff and nreloc for this.
* docs(native): move initializer guide under docs/guides/native
The documentation guide assigns analyst workflows to docs/guides/<domain>/.
Move the guide there, place its navigation and directory entries in the
Native binaries group, and update links from the docs index, CLI guide,
spec and authored skill. The public /native-initializers route is
unchanged.
The guide and spec also describe per-slot relocation coverage, retained
link-time records, Mach-O object relocations, undecoded bind streams,
the dyld_info_rebase resolution and unreadable names.
* fix(native): keep IFUNC and partly relocated ELF initializer slots unresolved
An absolute relocation against an STT_GNU_IFUNC symbol no longer reports
the resolver address as the target. Section relocation records now use
their real write width, so a record that writes only part of a slot,
starts inside it or repeats it leaves the slot unresolved instead of
reading a raw zero or dropping a .ctors slot as a sentinel.
On 32-bit ARM the Thumb bit is cleared when locating a target's section
and file offset, while value_va keeps the stored callable value.
* fix(native): locate Thumb Mach-O initializer targets and reject arm64_32 with a 64-bit header
On CPU_TYPE_ARM the Thumb bit is cleared when locating and naming a
target, since nlist values do not carry it. An arm64_32 image that
declares a 64-bit header is rejected as malformed rather than read with
8-byte slots. The guide and spec describe IFUNC relocations, partly
relocated section slots, Thumb targets and this rejection.
* fix(native): index initializer address lookups and keep ambiguous mappings unknown
ELF and Mach-O initializer lookups now build the shared file mapping
index once per image, so each slot and target lookup is logarithmic in
the number of load segments rather than a scan of every mapping.
An address that load segments map ambiguously no longer falls back to a
section header offset. Its file offset is reported as unknown and the
report is incomplete; only genuinely unmapped spans use the section
fallback.
* fix(native): report Mach-O bind names over the name budget
A bound import name longer than the 1024-byte name budget was dropped
without a trace, although it is the only identity of an unresolved
initializer target. It now counts toward the over-long name limitation
and makes the report incomplete.
* test(native): count mapping lookups instead of timing the load index regression
The load-mapping regression asserted a wall-clock bound, which is
sensitive to machine load. It now spies on the shared mapping module and
requires the same number of mapping scans and index builds for 8 and 64
slots, so a per-slot scan of every load segment fails deterministically
on a small fixture.
* fix(native): yield while decoding legacy rebase runs
* fix(native): preserve initializer mapping and coverage
* fix(native): index legacy fixup spans
* fix(native): preserve relocation uncertainty and bound bind lookup work
* fix(native): validate ELF slot mappings and yield section relocation scans
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Keep independent Objective-C class, metaclass, category and protocol records when an adopted-protocol list is unreadable. The shared list reader retains readable prefixes through tagged Result failures; consumers preserve partial/unknown semantics with unchanged limits. Advance the source-owned reader commitment to v3 and reject stale v2 snapshot bindings.
Validated with 232 focused tests, current-main and original-proposal RED checks, named provider-result/schema/identity controls, and a verified public GLFW Mach-O paired with independent LLVM/Python byte evidence. Ordinary binary results remain identical; a deliberately mutated count preserves ten rows instead of eight. The final head passes the real macOS CI lane, with twelve CLI tests including both new protocol-count cases over CLI and stdio MCP. Snapshot binding and same-version replay checks pass.
The original unchecked human declarations are preserved. The explicit maintainer readiness exception applies after technical CI and automated review, without adding a human-review attestation.
Fixes#8945
Full technical CI 42263548929 passes, including all eight shards and required aggregates. The Author readiness-only exception is explicitly authorized; no human-review attestation is added.
Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
An Objective-C category whose class field is null, or is bound to a
symbol other than `_OBJC_CLASS_$_`, was recorded as partial with
`category_class_unresolved`, but no issue was raised, so the
`objc_properties_categories` coverage facet reported `partial` with a
null reason. swiftc emits such categories for @objc members of an
extension on another module's Swift class and binds the class field to
the class metadata symbol (`_$s…CN`); Keynote and Notability carry them.
Report the reference as a `category_class_unresolved` issue naming the
bound symbol, or stating that the reference is null, matching the issue
already raised for an unreadable local class reference.
Use one lossless Mach-O name projection for symbols and dependency paths, retaining undecodable bytes and partial binding facts. Keep referenced NIB string failures unknown and preserve their source nodes through the shared lazy projection. Valid Unicode, readable sibling metadata and weak-bind scope remain usable.
Exercise the producer and CLI/MCP consumers, and align date-overlap and object-capacity fixtures with their owning archive contracts without relaxing admission or omission assertions.
Remove the test-only Objective-C property facade that discarded completeness. Verify its remaining semantics through portable Mach-O metadata decoding, including retained partial properties and located issues.
Decode the single IDA text result directly while preserving native JSON and structured-content precedence. Update the stale SDK deadline assertion to check the busy tool through its diagnostic owner.
Reuse filesystem-aware path selection for resource-only plist sessions so directory symlinks and trailing separators retain their meaning. Parse dyld bind names once as lossless text or exact bytes, preserving partial binding facts and independent valid metadata without invented class identities. Keep coverage issues separate from known opcode applicability and exercise both producer and generated Mach-O consumers.
Separate AMDGPU processors from feature-qualified note identities. Read Apple hidden ARM64 table rows once and preserve visibility through artifact, dylib and fuse consumers. Keep Objective-C++ template commas within type attributes and incomplete metadata unknown.
Validated provider/parser and production property regressions, Electron CLI/MCP consumers, and native Apple lipo -hideARM64 output through the production slice reader and public artifact inspection. LLVM execution remains unverified.
Fixes#6806Fixes#6799Fixes#6801
* feat(native): decode Swift nominal type declarations from __swift5_types
Fill swift_decls from the nominal type context descriptors that survive
stripping: kind (class, struct, enum, actor), own and qualified name,
module, generic flag, anonymous-context flag, metadata accessor and
descriptor location, with evidence citing the type record. Unresolved
parent contexts keep qualified_name null and the entry partial.
One shared reader walks each context once; class vtable recovery now
consumes its descriptors instead of re-reading the records, so a type
record that cannot be read keeps both facets partial. Remove the
never-populated swift_decls fields that descriptors do not carry.
Fixes#5341
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(native): bound Swift context walks and decode vtables in record order
Address review of the nominal-type reader:
- Cache intrinsic context depth (distance to the module) so a cached
parent cannot bypass the 32-context bound, and never cache a stop that
depends on where the walk began. Bound qualified names to 4096
characters so nesting cannot multiply name storage.
- Visit each descriptor as soon as its kind and name are read, so a
class vtable spends the record budget in record order instead of after
every later declaration.
- Report an accessor outside executable mapped code as null and keep the
declaration partial.
- Forward a name failure to vtable coverage only when the record is a
class or its kind is unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Decode direct Objective-C class names separately from nominal descriptors, retain indirect class bindings as partial facts, and preserve readable protocol and witness evidence when related bytes are unavailable.
Validated with 98 focused tests, check:ci, docs:check, and named-schema CLI/MCP replays of compiler-produced imported-class and struct fixtures plus an inert kind-3 control. The fixtures were inspected statically, never executed.
Fixes#5738
Resolve relative pointers using field-owned ABI encodings. Keep null, raw, rebased, imported and unknown targets distinct, and retain imported conformance rows with exact Mach-O binding provenance. Decode legacy rebase membership with source-derived memory and work bounds, preserving validated prefix facts when streams are incomplete.
Validation: check:ci, docs:check and build passed; 158 source tests and 20 schema/acceptance tests passed. Ten source-built Apple dispatch variants and four issue-specific CLI/MCP workflows passed without executing targets. Paired cold/warm CLI/MCP cost observations retained locally; model tokens and maximum-sized input runtime were not measured.
Closes#5683Closes#5685
BREAKING CHANGE: Swift conformance type_name and protocol_name can be null when names cannot be resolved; consumers must use typed type_binding and protocol_binding evidence. MachoImportBinding replaces the former Objective-C-specific binding type and schema.
Count examined and decoded vtable slots in the same population, preserving all returned slots and partial descriptor failures. Document the coverage unit and retain malformed-sibling and unresolved-slot checks.
Closes#5681
Join provider class observations only when selected-image identity and exact import bindings establish equivalence. Preserve distinct observations and unsupported coverage.
Refs #5607
Have method, property, ivar, and adopted-protocol list owners flag real budget omissions on returned class, protocol, and category records. Preserve known empty lists and existing decode reasons.
Validated 59 source tests, two built CLI controls, five static inspections of an Apple-clang fixture, and typecheck/lint. The target was never executed. Fixes#5543.
* fix(objc): isolate empty Objective-C protocol method selectors
A protocol method_list_t entry whose selector reached an empty string was
appended to objc_protocols and objc_protocol_records unchecked. The final
metadata schema then rejected the whole result, discarding every valid
class, protocol and category.
The protocol method decoder now skips only that entry and reports it as
a protocol failure. The protocol keeps its other method declarations, and
its record is marked partial with protocol_method_selector_empty.
Fixes#4540
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(objc): treat empty local category class names as unresolved
A category whose class reference pointed at a mapped local class with an
empty class_ro_t name took that empty string as class_name. The final
metadata schema then rejected the whole result, discarding every valid
class, protocol and category.
An empty local class name now fails the class reference the same way an
unmapped one does: the category is kept with class_name null,
class_source unresolved and a category_class_unresolved issue, and its
name, methods and protocols survive.
Fixes#4541
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Validate protocol and implementation selectors, ivar names and category
names before publishing records. Share validated local class identity
between class, superclass and category consumers, retaining unresolved
addresses and the decoder's failure reason.
Byte fixtures reproduced the reported validation failures. Final focused
4-file run: 118 passed; npm run check passed. Six existing CLI property
controls remain blocked before decoding by deep-provider auto-selection
ambiguity, as exposed by improved assertion diagnostics (#4555).
No Windows runtime or real malformed-application verification performed.
Refs #4540, #4541, #4533, #4534, #4115, #4555
* fix(native): reject empty Swift class vtable owner before slot insertion
Throw an explicit RangeError within the descriptor recovery block when a Swift class vtable descriptor class name is empty. This prevents emitting malformed slots that fail final schema validation, allowing partial coverage and valid sibling descriptors to be preserved. Fixes#4369
* test(native): verify decoding continues for valid Swift vtable siblings after a malformed descriptor
Consume signed and unsigned LEB operands through their terminators while validating 64-bit payloads and bounded extension. Preserve independent decoded metadata when a malformed stream fails.
Co-authored-by: Arjun Prabhulal <arjun.prabhulal@gmail.com>
An Objective-C category whose nonzero class reference pointed outside
mapped metadata failed as a whole, discarding its readable name, method
selectors and implementations. The category decoder now resolves the
local class name in its own boundary: on failure the category keeps its
facts with class_name null and class_source unresolved, and a
category_class_unresolved issue records the unreadable reference in the
category coverage.
Fixes#4012
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(native): record an empty Objective-C protocol name as a protocol failure
A protocol declaration whose name was an empty NUL-terminated string was
accepted as decoded, so whole-result validation of objc_protocols[].name
failed and inspect-native-dispatch-metadata discarded every decoded
class from the same image. The protocol decoder now rejects the empty
name inside its per-protocol boundary, as the class decoder already
does, so the protocol becomes a recorded partial-coverage failure and
independently decoded classes are retained.
Fixes#3873
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(native): decode adopted protocols before rejecting an empty parent name
Review follow-up. The empty-name check ran before the adopted-protocol
list was traversed, so a protocol declared only through an empty-named
parent's list was dropped. Adopted protocols are independent
declarations; traverse the list first, then reject only the parent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(native): retain valid Objective-C properties beside a malformed record
readObjcPropertyList decoded a whole property_list_t in one operation.
When a later entry's name pointer was unmapped, the list-level catch
discarded the properties already decoded. An empty property name passed
decoding and then failed schema validation of the whole result, so
inspect-native-dispatch-metadata exited 1 with no metadata.
Each property_t entry is now decoded on its own. A failing entry, or an
empty name, becomes a property_decode_failed issue at the entry address,
and sibling properties are retained. Incomplete-attribute issues also
report their entry address. List-header failures still fail only that
list.
Fixes#3336
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(native): cover property record isolation on every platform
Move the synthetic Objective-C property Mach-O into a shared fixture and
decode it through decodeAppleDispatchMetadata in a portable test, so
Linux and Windows runs also catch a regression that drops valid sibling
properties. The macOS CLI cases keep exercising the built command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(native): honor Mach-O chained pointer locations and library ordinals
Walk declared page starts and next links before decoding chained pointers,
preserving plain pointers between fixups, zero-offset rebases, and known
facts in malformed chains. Interpret positive dylib ordinals with dyld's
special-ordinal cutoff so valid dependency provenance is retained.
Give the Swift verification fixture an explicit module name so link-mode
filenames do not produce invalid identifiers.
Validation: 46 focused regressions; pre-fix reproductions in an isolated
copy; real macOS CLI/MCP verification of 10 compiled Objective-C/Swift,
arm64/arm64e, chained/legacy and symbols/stripped fixture variants.
* perf(native): reuse parsed Mach-O chain membership
* test(native): validate parsed-chain repair against local gates
* test(native): pin chained fixup page failure provenance
* fix(native): bound parsed chained page facts and metadata
* test(server): pin shared partial Evidence provenance
---------
Co-authored-by: baron <richstyles@gmail.com>
* fix: bind identity and coverage to the producing rule
Logical paths, container families, examined bytes, path-segment conventions, destination collisions, file-id leases, Mach-O CPU selection, and firmware cleanup now follow the observation that owns each rule.
* fix: fail unmatched Mach-O slices and keep firmware roots independent
A fat target whose architecture lipo did not list now stops before slice tools run. Chained fixups still count unread LC_DYLD_INFO rebase bytes, and a firmware cleanup failure no longer blocks the next workspace.
* test: cover path identity and runtime families at the projection boundary
NFC joins and segment conventions are now asserted by the path resolver, the Apple projection, and a real APK inventory instead of helper unit tests.
* test: expect unread dyld rebase bytes in the Apple dispatch fixture
The legacy LC_DYLD_INFO fixture keeps a rebase range this reader does not decode, so the public CLI and MCP check now requires that partial coverage beside the bind opcodes.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
BREAKING CHANGE: Objective-C attribute tokens now contain only name and value. Properties report nullable atomicity and readonly facts; class flags, ivar counts, and method requirement flags are nullable when unobserved.
Replace inline magic comparisons with an exhaustive fatHeaderFormat
switch and add a regression test locking in rejection of 32-bit
slice payloads inside little-endian containers. Behavior-preserving:
the new test passes on the old implementation.