Commit Graph

2602 Commits

Author SHA1 Message Date
morluto 93aa9eb5c2 fix(process): harden filesystem snapshot identity and cancellation (#956)
* fix(process): bind snapshots to captured file identity

* fix(process): honor snapshot cancellation for empty files

* test(process): verify snapshot descriptor cleanup

* fix(process): preserve snapshot cancellation results

* fix(process): preserve non-cancellation capture failures

* test(process): verify descriptor cleanup with fstat

* fix(process): detect snapshot changes by ctime

* test(process): prove snapshot ctime invalidation
2026-10-07 23:45:23 +08:00
morluto 9f496ef2d4 fix(native)!: preserve incomplete native UI captures (#991)
* fix(native): preserve unknown accessibility child counts

* fix(native): align helper buffer with capture budget

* fix(native): align Swift helper JSON wire size

* fix(native): bound raw helper output to scenario budget
2026-10-07 23:44:41 +08:00
morluto 0a4caf4a0a fix(evaluation): canonicalize Unicode argument keys (#980) 2026-10-07 23:19:49 +08:00
Namnarak 98b2b027af fix(linux): improve Hopper reliability and CachyOS support (#963)
* fix(linux): support CachyOS Hopper hosts

* fix(config): reuse user-local Hopper launcher

* fix(hopper): harden Linux demo dialog handling

* chore: retrigger CI after PR title fix

* fix(linux): align Hopper defaults and support docs

---------

Co-authored-by: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-07 23:16:48 +08:00
morluto d5c43d65f0 fix(cli): preserve output and comparison input validation (#981) 2026-10-07 23:04:54 +08:00
morluto a45fe86a39 fix(build): validate installed dependencies before cache hits (#982) 2026-10-07 23:01:01 +08:00
morluto 71ac83f3dd fix(apple): traverse keyed archive hierarchy collections (#976) 2026-10-07 23:00:43 +08:00
morluto fb3749aff6 fix(android): align runtime suffix inference (#977) 2026-10-07 23:00:22 +08:00
Kaoru0822 6fc77206e4 Merge remote-tracking branch 'origin/main' into feat/dylib-resolution 2026-10-07 14:48:35 +00:00
Kaoru0822 90b25f2e30 Merge origin/main into feat/native-call-observation
Follow #973's native ownership: the call-observation schemas move to
src/domain/native/, and the contract now lives in src/contracts/native/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:47:05 +00:00
Ysopwnable ea4db4c9f7 refactor(native): group analyst semantics workflows and contracts (#973) 2026-10-07 22:40:48 +08:00
Kaoru0822 a11c6bd5e4 Merge origin/main into feat/native-call-observation
observe-native-calls now runs through composition/directAnalysis, where #965
moved runProviderAnalysis.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:17:08 +00:00
Kaoru0822 3d889dc934 Merge remote-tracking branch 'origin/main' into feat/dylib-resolution
# Conflicts:
#	docs/product-catalog.json
#	docs/verification/managed-conformance-manifest.json
#	skills/reverse-engineer-anything/SKILL.md
#	src/generatedMcpToolCatalog.ts
2026-10-07 14:12:18 +00:00
Ysopwnable 33d4761cc7 refactor(binary): move production composition outside application workflows (#965) 2026-10-07 21:56:58 +08:00
Ysopwnable b5afa5f91e feat(browser): attribute native execution and listener sources (#917)
* feat(browser): attribute native execution and listener sources

Integrate finite native precise-coverage windows and direct DOM listener inspection through shared CLI/MCP workflows, exact session script identities, inline source evidence and owned instrumentation cleanup.

Refs #881, #774

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): preserve runtime identity and settle fixture cleanup

Retain complete reported initiator objects, reject changing loader availability, propagate the selected operation through main-frame authorization and complete effect/help inventories. Close only the synthetic owned Chrome via its native endpoint, await process-group settlement and preserve primary verification errors during cleanup.

Refs #881

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): settle invalid events and preserve document evidence

Accept same-document URL changes with proven stable loader identity, retain metadata without inventing ownership, terminate malformed event collection immediately, and sanitize known transport URLs without erasing sourceURL declarations.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): end detached target windows and sanitize coverage identities

Reuse the existing flat-session event matcher, retain prearming termination, and apply the source identity policy to coverage URLs. Add real MCP target-close verification and producer regressions for detachment orderings.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): retain final sample metadata and settle fatal protocol failures

Keep source inventory open through the resetting sample, propagate fatal wire failures without outstanding commands, and check listener collection failures after final document validation.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)

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

* fix(browser): require default execution worlds for website attribution

Preserve native context and world metadata without treating same-frame isolated or unknown contexts as website sources. Verify actual Chrome isolated function execution before excluding its coverage, and cover ambiguous world metadata with producer regressions.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)

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

* fix(browser): revalidate runtime source joins and selector failures

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-07 21:45:07 +08:00
Kaoru0822 a0f5e33bd8 Merge remote-tracking branch 'origin/main' into feat/native-call-observation
# Conflicts:
#	package.json
2026-10-07 13:39:42 +00:00
Kaoru0822 9a487a4e00 fix(artifacts): flag truncated Mach-O headers and keep canonicalization denials
- A file with a recognized Mach-O or FAT magic but fewer than 8 bytes is a
  malformed image, so it stays visible in coverage and root diagnostics.
- Canonicalize the analyzed root and target inside the translated region,
  so a permission revoked after open_binary keeps its reason and path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:29:12 +00:00
Kaoru0822 e5c6fccc35 Merge origin/main into feat/dylib-resolution
Follow #952's Apple ownership: the Mach-O load-command reader, dylib
resolution adapter and fixture move to src/artifacts/apple/, the resolver,
dyld path semantics and findings to src/domain/apple/, and the dylib lane
helper to scripts/verify/apple/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:28:14 +00:00
Kaoru0822 9837203234 feat(native): observe function and Objective-C method calls under LLDB
Add observe_native_calls (CLI: observe-native-calls <path> <input-json>). It
launches the active Mach-O as an owned process under `lldb --batch`, stops at
caller-selected functions or Objective-C methods, records each entry and
auto-continues:

- thread, image, symbol, load and file address;
- raw integer argument registers and optional caller frames;
- for methods, the selector read from _cmd and the receiver's dynamic class,
  from LLDB's runtime reader without running target code.

No expression is evaluated and no existing process is attached. The run ends
on exit, max_events or duration_ms; REA then kills the process and confirms
that it is gone. The result also carries exit status, bounded stdout/stderr,
breakpoint resolution with partial coverage for unresolved requests, and
limitations. A target LLDB may not debug fails with a debugger-attach-denied
reason and remediation.

verify:native-calls checks the tool through the CLI and stdio MCP against a
compiled fixture, compares breakpoint addresses with nm, exercises every
outcome, and checks hardened-runtime targets with and without get-task-allow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:22:55 +00:00
ysopwnable ef1a0cc65a refactor(apple): group artifact producers and verification (#952)
* refactor(apple): group artifact producers and verification

* test(apple): run affected native plist CLI regressions
2026-10-07 21:09:33 +08:00
Kaoru0822 5e334a0e12 fix(artifacts): propagate conditional loads and bind digests to parsed images
- Edges below a conditional fallback now carry loader_conditional, reuse of
  a conditional image by install name is conditional, and their findings say
  they apply only if that image loads.
- Hash each traced image only if it is still the file whose headers were
  parsed (device, inode, size and change times), before and after hashing.
- Resolve explicit roots segment by segment, so a root below a symlinked
  directory that points outside the analyzed root is rejected.
- Require a complete 16-byte LC_CODE_SIGNATURE command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:58:20 +00:00
Kaoru0822 9049620dfe Merge remote-tracking branch 'origin/main' into feat/dylib-resolution
# Conflicts:
#	docs/product-catalog.json
#	docs/verification/managed-conformance-manifest.json
#	skills/reverse-engineer-anything/SKILL.md
#	src/generatedMcpToolCatalog.ts
2026-10-07 12:54:53 +00:00
Kaoru0822 ef245c0bd0 fix(artifacts): trace .app-named files standalone and flag empty FAT tables
- Treat the target as a bundle only when it was opened from an app bundle
  directory (it carries the bundle's Info.plist); a regular Mach-O file whose
  name ends in .app is traced from its parent directory.
- Classify a FAT header with zero architecture records as malformed, so it
  stays visible in unclassified roots and coverage.
- State that dylib compatibility versions are not compared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:25:37 +00:00
Kaoru0822 19f01e2610 Merge remote-tracking branch 'origin/main' into feat/dylib-resolution
# Conflicts:
#	docs/product-catalog.json
#	docs/verification/managed-conformance-manifest.json
#	skills/reverse-engineer-anything/SKILL.md
#	src/generatedMcpToolCatalog.ts
2026-10-07 12:23:08 +00:00
Kaoru0822 3e24a72465 feat(native): decode chained fixups, binds, ObjC categories and properties
inspect_native_dispatch_metadata read pointer fields as stored bytes, so
chained-fixup images (the default since Xcode 13) decoded no classes, and
superclasses from other images were always unresolved.

- Decode LC_DYLD_CHAINED_FIXUPS pointer formats 64, 64_OFFSET, ARM64E,
  ARM64E_USERLAND and ARM64E_USERLAND24 with import formats 1-3, and
  interpret LC_DYLD_INFO bind, weak-bind and lazy-bind opcode streams.
- Name external superclasses from their _OBJC_CLASS_$_ binds.
- Decode class_ro_t baseProperties and __objc_catlist category_t records
  (instance/class methods, protocols, properties) into objc_categories;
  category methods carry their category name.
- Report the fixup encoding in a pointer_fixups coverage facet.
- verify:apple-dispatch builds the fixture with dyld-info and chained
  fixups, plus arm64e on Apple silicon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:18:24 +00:00
morluto 2366bda37b fix(artifacts): harden reader lifecycle boundaries (#951)
* fix(artifacts): retain ASAR filesystem failure reasons

* fix(artifacts): avoid blocking on replaced FIFO entries

* test(artifacts): type the ASAR reader iterator

* fix(artifacts): classify filesystem-shaped ASAR errors

* test: account for POSIX FIFO fixture utility
2026-10-07 20:00:24 +08:00
morluto e0d76ae80d fix(mcp): advertise reserved process environment key (#949) 2026-10-07 19:58:51 +08:00
morluto ac3bae3cb9 fix(native-ui): handle incomplete accessibility child collections (#944)
* fix(native-ui): align verifier with scenario contract

* perf(native-ui): reuse accessibility child counts

* fix(native-ui): handle incomplete child collections
2026-10-07 19:52:16 +08:00
morluto 9e39795895 fix(android): bound fragmented JADX MCP frame memory (#937)
* perf(android): avoid repeated MCP frame copies

* fix(android): bound fragmented MCP frame memory

* style(android): format JADX transport changes
2026-10-07 19:51:08 +08:00
Kaoru0822 91280393cd fix(artifacts): defer lazy loads and tighten Mach-O validation
Address review findings in trace_dylib_resolution:
- Resolve LC_LAZY_LOAD_DYLIB dependencies without traversing them, since
  dyld loads them on first use. An unresolved one becomes
  `lazy-load-unresolved`, not a launch failure.
- Accept FAT tables up to 128 records, as target opening does. A table
  that names no Mach-O CPU type, such as a Java class file, is not
  Mach-O.
- Require 8-byte load-command alignment in 64-bit images. 1,508 real
  slices still match otool.
- Report EACCES/EPERM while probing, reading, or hashing as an
  `unavailable` failure naming the code and path, rather than generic
  io.

Findings and limitations move to dylibResolutionFindings.ts to keep the
resolver under the module size limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:50:00 +00:00
ysopwnable 28713f9b4d refactor(managed): group capability workflows and verification (#926) 2026-10-07 19:22:04 +08:00
Kaoru0822 a0ec3e2016 fix(artifacts): follow dyld slice grading and report unparsed images
Address review findings in trace_dylib_resolution:
- Choose child slices by dyld's graded architectures, so an x86_64h
  process loads a generic x86_64 slice instead of reporting
  architecture-missing.
- Read FAT containers with the byte-swapped FAT_CIGAM and FAT_CIGAM_64
  magics, which target opening already accepts.
- Report string-bearing load commands too short to hold their string
  offset as malformed instead of failing with a RangeError.
- Keep recognized but unsupported images as an `unsupported` candidate
  outcome. It is undeterminable like an outside-root path, not
  malformed.
- List Mach-O files that do not parse during root enumeration as
  unparsed images, so coverage is partial rather than silently complete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:07:31 +00:00
Jay Hemnani 37d2ebac4c fix(artifacts): accept the bundle subject when extracting an app bundle (#891)
* fix(artifacts): accept the bundle subject when extracting an app bundle

For a .app target the session target is the bundle's executable, while the
artifact provider reports the bundle itself as the subject. The subject
check exempted inventory_artifact and inspect_artifact but not
extract_artifact, so extracting any .app failed with execution_failure after
the output tree had already been written, and the output path was never
reported.

* refactor(binary): rename artifact bundle subject helper

isArtifactInventorySubject also covers extract_artifact for .app
bundles, so name it for the shared bundle-subject exemption.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 19:04:55 +08:00
Kaoru0822 63800ff5a2 Merge remote-tracking branch 'origin/main' into feat/dylib-resolution
# Conflicts:
#	docs/product-catalog.json
#	docs/verification/managed-conformance-manifest.json
#	skills/reverse-engineer-anything/SKILL.md
#	src/generatedMcpToolCatalog.ts
2026-10-07 11:04:20 +00:00
Jay Hemnani 45fcd28b40 fix(javascript): resolve bare source-map and worker URLs next to the script (#890)
* fix(javascript): resolve bare source-map and worker URLs next to the script

A sourceMappingURL like `main.js.map` (the default of webpack, esbuild,
rollup, Vite and rolldown) and `new Worker("worker.js")` were resolved as
module specifiers, so the bare name was looked up as an npm package and the
map or worker script was never linked. Resolve them as URLs relative to the
declaring script.

* fix(javascript): tighten url-reference resolution edge cases

Use looksExternal for non-module contexts so protocol-relative URLs
cannot be misread as root-absolute paths, cover url-reference unit
cases, and assert bare service-worker script resolution.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 19:04:15 +08:00
Kaoru0822 aa8082ea6c Merge pull request #913 from morluto/fix/uikit-runtime-connections
fix(artifacts): project UIKit runtime outlet and event connections
2026-10-07 04:00:25 -07:00
Kaoru0822 b3f013fa18 Merge pull request #899 from morluto/fix/interface-builder-plist-data
fix(artifacts): decode flat keyed-archive NIBs with data and shared references
2026-10-07 03:59:54 -07:00
Kaoru0822 2ed89e6529 Merge pull request #910 from morluto/feat/ios-app-bundles
feat(native): open iOS-style and iOS-on-Mac wrapper app bundles
2026-10-07 03:59:41 -07:00
morluto 71e5cb1640 chore: merge main and regenerate combined catalog metadata 2026-10-07 18:44:35 +08:00
morluto fd552a8c4b chore: merge main and regenerate combined catalog metadata 2026-10-07 18:44:34 +08:00
morluto be121d87eb chore: merge main and preserve keyed archive regressions 2026-10-07 18:44:01 +08:00
morluto b9292516f4 fix(process): retain provider output until streams close (#928) 2026-10-07 18:39:10 +08:00
morluto f826aa893f fix(browser): preserve evidence through deep AST analysis (#924) 2026-10-07 18:36:18 +08:00
Kaoru0822 11b7f918c2 feat(artifacts): trace Mach-O dylib resolution in bundles
Add trace_dylib_resolution (CLI trace-dylib-resolution) to the artifact
family. For the active Mach-O, or every executable in the active .app
(the main app, XPC services, extensions, login items, helpers), it
reports which file each dylib load reaches and how.

A pure TypeScript reader decodes FAT and Mach-O load commands:
LC_LOAD/WEAK/REEXPORT/LAZY/UPWARD_DYLIB, including the newer
dylib_use_command encoding with weak, re-export, upward and delayed-init
flags, plus LC_ID_DYLIB, LC_RPATH, LC_DYLD_ENVIRONMENT and code-signature
presence. Malformed tables are reported with the failing command instead
of being guessed.

Resolution follows dyld:
- @executable_path comes from each process root;
- @loader_path comes from the loading image, or from the owner of the
  LC_RPATH entry being expanded;
- @rpath searches the loader's rpaths first, then up the load chain;
- dependencies load dependents-first in load-command order, once per
  process, and a matching install name reuses an already loaded image;
- symlinks are followed inside the analyzed root, and escapes stop.

Every candidate path is reported with its outcome. Each edge resolves to
resolved, conditional (an outside-root candidate such as /usr/lib/swift
precedes), unresolved, or undetermined. Absolute and shared-cache system
paths are never checked against the host. Derived findings cover
unresolved required or weak loads, absent earlier @rpath candidates (with
library validation left unknown), and LC_DYLD_ENVIRONMENT.

verify:macos-bundle now also:
- checks every traced image against otool -l;
- asserts each resolution status on a clang-built fixture that adds a
  missing Overrides rpath, an absolute rpath, and a delay-init library;
- compares the predicted load order of two process roots with what dyld
  loads under DYLD_PRINT_LIBRARIES.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 10:31:17 +00:00
Kaoru0822 b956bd589f Merge branch 'fix/dmg-apfs-detach' into feat/macos-bundle-anatomy 2026-10-07 10:28:20 +00:00
Kaoru0822 62634e4c01 fix(artifacts): keep the post-snapshot detach check out of provenance
The inventory snapshot captures reader provenance before close() runs,
so a `hdiutil info -plist` entry recorded during cleanup never reached
CLI or MCP results. Detach entries already share that timing. Record
neither instead of implying the query is observable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 10:28:03 +00:00
Kaoru0822 28fd49f0f6 Merge pull request #889 from morluto/fix/managed-comparison-undecoded-signatures
fix(dotnet): compare members with undecoded signatures by exact identity
2026-10-07 03:22:54 -07:00
morluto 9a15525298 perf(cli): defer unused catalog work during command startup (#920)
perf(cli): defer catalog digests and use canonical cache scope
2026-10-07 18:16:10 +08:00
Kaoru0822 dd3e7aef0d feat(apple): project macOS bundle anatomy in application graphs
project_apple_application_graph accepted only IPA inventories. It now
also projects macOS .app directories and ZIP or DMG inventories that
contain applications. It reports application roots, platforms, and
every nested bundle with its path-convention role, layout, parent,
Info.plist path, executable candidates, and signing paths:
- roles: app extensions, XPC services (including inside frameworks),
  frameworks, login items, system and driver extensions, plug-ins,
  resource bundles, and helper or nested applications;
- privileged helpers in Contents/Library/LaunchServices and launchd
  plists in Contents/Library/LaunchAgents or LaunchDaemons;
- direct files of Contents/Helpers;
- symlinks by path. Their targets are not inventoried, so versioned
  frameworks are described through their real Versions/<version>/
  directories.

AppleDouble sidecars (._* and __MACOSX/) are excluded from roles. A DMG
whose contents could not be inventoried is reported as partial. Other
inventory formats remain input errors. The projection still reads no
plist or CMS semantics; it points callers at inspect_plist.

The result schema is additive. projection_id now covers the new fields,
so IPA projection IDs differ from earlier versions.

verify:macos-bundle compiles a source-owned app with clang (CLT only).
It packs it as a directory, a ditto ZIP, and an APFS DMG, and checks
identical anatomy through the CLI with stdio MCP parity. It runs in the
macOS CI job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 10:06:48 +00:00
Kaoru0822 b72c079a9a fix(artifacts): accept APFS image disks ejected with their container
An APFS disk image attaches as an image disk plus a synthesized APFS
container, and hdiutil reports both as whole disks. Detaching the
container also ejects the image disk, so the reverse-order detach then
failed with "No such file or directory" and every APFS DMG inventory
ended in "DMG detach or mount-root cleanup failed". APFS is the default
format of `hdiutil create` on current macOS.

When a detach fails, ask `hdiutil info -plist` whether the device is
still attached. A device that is gone counts as detached; one that is
still listed, or whose state cannot be read, remains a cleanup failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 10:06:37 +00:00