Commit Graph
699 Commits
Author SHA1 Message Date
Iwakurakaoru0822andClaude Opus 5.5 b9d4d8301f fix(javascript): keep computed-method XHR request URLs
A computed XHR method, as in `xhr.open(method, "/api")`, no longer
discarded an endpoint that main reports. Keep the URL when it is an
HTTP(S)/WebSocket URL or a path; fs flags and window targets such as
`r` and `_blank` still produce no endpoint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 23:09:18 -07:00
Iwakurakaoru0822andClaude Opus 5.5 1be370543f fix(javascript): read open() endpoints only from XHR method/URL pairs
Static endpoint extraction treated any `.open(_, "literal")` call as
`XMLHttpRequest.open(method, url)`. In application and web bundle
analysis, `fs.open("/tmp/data.txt", "r")` became the network endpoint
`r` and `window.open(url, "_blank")` became the endpoint `_blank`.

Read the URL only when the first argument is a literal HTTP method: a
standard method in any case, or an uppercase extension token such as
WebDAV `PROPFIND`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 23:02:58 -07:00
morlutoandCursor Agent e0fd8207a1 feat(application): wire Android and Apple inventory graph tools (#852)
* feat(application): wire Android and Apple inventory graph tools

Expose project_android_application_graph and project_apple_application_graph
through CLI and MCP so authenticated inventory Evidence can be projected
without a provider launch.

* fix(application): use producer root occurrence IDs in graph examples

Catalog examples constructed root occurrence IDs from artifact_id +
logical_path, but inventory validation authenticates "." with
{ root: root_artifact_id }. Align the examples and regenerate catalogs
after rebasing onto main (application family count 11).

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 13:34:48 +08:00
morlutoandCursor Agent da0970672d refactor(domain): split Interface Builder keyed-archive parse from graph builder (#859)
* refactor(domain): split Interface Builder keyed-archive parse from graph builder

* fix(domain): drop unused Interface Builder type re-exports

Knip failed Static checks because the split re-exported object and
connection types that no caller imported.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 13:30:25 +08:00
morlutoandCursor Agent 676959ecb5 refactor(native): split Apple dispatch metadata decode facets (#855)
Extract Mach-O/FAT selection, Objective-C class/method/ivar decode, and
Swift conformance/witness facets so AppleDispatchMetadata stays a thin
orchestrator without changing decode semantics.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 13:22:31 +08:00
morlutoandCursor Agent b7df5b7805 refactor(ghidra): extract createClient and load-image attestation (#856)
Move AnalysisClient construction into GhidraProviderClient and the DOS
load-image attestation path into GhidraLoadImageAttest so GhidraProvider
stays a thin candidate adapter without behavior changes.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 13:22:23 +08:00
Kaoru0822andClaude Opus 5.5 4aa2b60c1d fix(native): keep echoed codesign paths out of signature fields (#865)
codesign echoes the executable path and signing identifier verbatim,
and an ad hoc identifier derives from the file name. A file name with
line breaks added forged Authority lines, a signed file named after
codesign's unsigned message was reported unsigned, and path text could
supply entitlements. Parse display fields after the exact echoed path
and identifier, classify unsigned output by exit status, and read
requirements and entitlements from stdout.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:20:12 +08:00
Kaoru0822andClaude Opus 5.5 4e17be5705 fix(setup): read an OpenCode V2 server named type as a table entry (#866)
Only a string type is the V1 entry discriminator; a native mcp.servers
table may hold a server object named type.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:20:02 +08:00
ysopwnable bb19c9477e refactor: colocate investigation record implementation (#867) 2026-10-07 13:18:39 +08:00
Kaoru0822 f608127635 Merge pull request #843 from morluto/fix/exact-empty-graph-identities
fix(javascript): keep exact empty values in graph identities
2026-10-06 22:11:07 -07:00
Kaoru0822 957069d14d Merge pull request #864 from morluto/fix/opencode-v2-servers
fix(setup): register OpenCode V2 configurations in mcp.servers
2026-10-06 22:07:29 -07:00
Kaoru0822 93091abb4d Merge pull request #863 from kaoru0822-kitauji/fix/smol-toml-advisory
fix(deps): remediate smol-toml advisories
2026-10-06 22:04:59 -07:00
Kaoru0822 c57f1b74e0 Merge pull request #857 from morluto/fix/app-xml-plist-executable
fix(target): decode app Info.plist executables with an XML parser
2026-10-06 22:04:47 -07:00
N0zoM1z0 3427593daf build: verify resolved module boundaries (#862) 2026-10-07 13:02:28 +08:00
Iwakurakaoru0822andClaude Opus 5.5 bddeb634b5 fix(errors): report union input issues at the union's path
Zod reports union branch issues relative to the union, so a missing
union-typed argument such as trace_application_feature's seed was
reported at the request root, once per branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 22:02:25 -07:00
Kaoru0822andClaude Opus 5.5 3b92a2bced fix(native): keep integral plist reals beyond the JSON range as reals (#860)
plutil's JSON spells an integral <real> such as 9007199254740992 like an
<integer>, so the JSON path labeled it an exact integer. When the JSON
holds an unsafe integral number, read element types from plutil's XML
conversion; numbers whose origin stays ambiguous are reported as decoded
with an explicit limitation.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:01:26 +08:00
morlutoandCursor Agent 8b9940a7b5 refactor(cli): split core analysis command registrar (#858)
Extract binary overview/procedure and native load-image/annotation
registrars so coreAnalysisCommands stays a thin wiring entry point.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 13:00:38 +08:00
Iwakurakaoru0822 b6d9acca63 Merge remote-tracking branch 'origin/main' into fix/exact-empty-graph-identities
# Conflicts:
#	docs/product-catalog.json
#	docs/verification/managed-conformance-manifest.json
#	skills/reverse-engineer-anything/SKILL.md
#	src/generatedMcpToolCatalog.ts
2026-10-06 22:00:37 -07:00
morlutoandCursor Agent 2d4a910fcd fix: preserve native UI failure reasons and dedupe version literals (#854)
Keep adapter/OS helper failures in diagnostics instead of replacing them
with a canned remediation sentence. Share browserVersionSchema, Node
support prose, and JADX heap/remediation constants so release pins stay
authoritative.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 13:00:24 +08:00
Iwakurakaoru0822andClaude Opus 5.5 35e5508fd0 fix(javascript): advertise the exact empty seed rule and match empty API keys
Express the empty-seed rule as a JSON-Schema-representable union, so
the advertised trace_application_feature schema rejects what the
server rejects, and match context-bridge seeds on the exact api_key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 22:00:14 -07:00
Iwakurakaoru0822andClaude Opus 5.5 69d8afefc1 fix(setup): register OpenCode V2 configurations in mcp.servers
OpenCode V2 reads native server entries from mcp.servers, and a native
entry takes precedence over a V1 mcp.<name> entry. After OpenCode
migrated a configuration, setup wrote an ignored V1 entry, status
reported REA as missing, and uninstall left the native entry in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:58:20 -07:00
Kaoru0822 c55ae3b9ec fix(deps): remediate smol-toml advisories 2026-10-06 21:55:36 -07:00
N0zoM1z0 166dcd21d0 feat(javascript): recover readable modules with Wakaru (#848)
* feat(javascript): recover readable modules with Wakaru

Integrate pinned upstream source behind a typed optional recovery port,
preserve source identity and producer provenance, and publish verified
artifacts for existing JavaScript analysis through CLI and MCP.

Add focused real-tool CI with genuine bundler fixtures and bounded
resource, cancellation, cleanup, schema and packaged-artifact checks.

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

* fix(javascript): align recovery catalog and browser verification

Share canonical Wakaru provider identity, describe CLI mode options, and
format the new workflow test. Disconnect the real page transport after
its observation readiness progress instead of a fixed delay.

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

* refactor(javascript): consume the investigation evidence writer

Verify that the SDK recovery handler records complete Evidence through the newly shared investigation owner.

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

* chore(test): account for isolated recovery fixture compilers

* fix(javascript): validate recovery paths before acquiring the engine

Return field-specific invalid_format diagnostics for relative paths and verify compiled CLI/MCP parity even when the optional engine is unavailable.

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

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-07 12:46:13 +08:00
Iwakurakaoru0822andClaude Opus 5.5 c182f72ad3 fix(target): decode app Info.plist executables with an XML parser
The pattern-based reader decoded entities twice, ignored numeric
character references and CDATA, and could match a commented or nested
CFBundleExecutable key, so valid app bundles reported a missing program.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:40:32 -07:00
Iwakurakaoru0822 6cc45e8dc9 Merge remote-tracking branch 'origin/main' into fix/exact-empty-graph-identities
# Conflicts:
#	docs/product-catalog.json
#	docs/verification/managed-conformance-manifest.json
#	skills/reverse-engineer-anything/SKILL.md
#	src/generatedMcpToolCatalog.ts
2026-10-06 21:36:34 -07:00
Iwakurakaoru0822andClaude Opus 5.5 e20da1f205 fix(javascript): match exact empty literal channels and seeds
Pair the same empty IPC channel, context-bridge key, or endpoint value
across application versions by its exact value, and accept an exact
empty feature seed while rejecting an empty containment seed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:35:59 -07:00
N0zoM1z0 4a6c17ce83 refactor: declare auxiliary capabilities from source (#853) 2026-10-07 12:32:34 +08:00
Kaoru0822 c9f49db907 Merge pull request #846 from morluto/fix/plist-exact-large-integers
fix(native): report exact plist integers beyond the JSON number range
2026-10-06 21:31:49 -07:00
morluto f72931d9dd test: eliminate fixture races and prune redundant scaffolding (#849)
* test: eliminate fixture races and prune redundant scaffolding

* fix(test): publish launcher capture readiness without renaming
2026-10-07 12:25:37 +08:00
morlutoandCursor Agent 5cbf06c7ad fix(ghidra): admit the 12.1 line and the install's JDK range (#840)
* fix(ghidra): admit the 12.1 line and the install's JDK range

The provider treated the verified Ghidra 12.1.4 build and JDK 21 as the only
legal installation, so a working 12.1.x package or a newer JDK was rejected
before analysis started.

Admission now follows the 12.1 release line and application.java.min/max.
A compatible build other than 12.1.4 keeps its observed version and records
that the bridge was verified against 12.1.4.

Fixes #821

* fix(ghidra): stop pinning the NativeAOT build to one version string

The build script still rejected every Ghidra release except the literal
12.1.4 and every javac except major 21. It now accepts the 12.1 line and
javac 21 or newer, compiles with --release 21, and records the observed
Ghidra version. The JADX engine version uses the audited release constant.

* fix(ghidra): report unverified builds on analysis results

Session open uses health only as a startup gate and discards that
execution, so the unverified-build limitation never reached CLI or MCP
results. Attach it to every Ghidra execution for that install.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 12:24:36 +08:00
morlutoandCursor Agent bef4321afb fix(firmware): accept the verified Binwalk and Unblob release lines (#844)
* fix(firmware): accept the verified Binwalk and Unblob release lines

Exact --version equality rejected every build except Binwalk 3.1.0 and
Unblob 26.6.4, then stored that constant as the observed engine version.
Admit the 3.1 and 26.6 lines, keep the audited build as verified, and
report the banner that actually ran.

* chore(docs): regenerate skill metadata after firmware contract text

docs:check failed because SKILL.md lagged the Binwalk/Unblob release-line
tool descriptions.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 12:19:28 +08:00
Kaoru0822andClaude Opus 5.5 3f1a77f68e fix(artifacts): report which path constraint failed (#847)
Artifact path failures told callers to "inspect the reported path" but
reported none: `ArtifactReaderFailure` messages such as
`Artifact path collision: ...` were dropped when converted to
`ArtifactOperationError`, leaving only `{ operation, reason: "path" }`.

Carry the failure message into `details.detail` for artifact tools and
JavaScript application analysis. Name both spellings in case-fold
collisions and include the JSON-escaped input in unsafe and
non-normalized path messages.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:17:16 +08:00
Iwakurakaoru0822andClaude Opus 5.5 f85056d83e fix(native): keep plist XML element types for large numbers
The XML fallback inferred an integer from `Number.isInteger`, so an
integral `<real>` beyond 2^53 was misreported as an unknown integer.
Read the `<integer>` and `<real>` literals from plutil's XML text instead:
an unsafe integral number that matches one `<integer>` literal and no
`<real>` gets its exact decimal; a number that could be either stays as
decoded with a limitation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:13:11 -07:00
Iwakurakaoru0822andClaude Opus 5.5 527b76ef78 fix(javascript): leave empty application values unlabeled
A synthetic `""` label for an empty application-graph value could still
be matched by a literal `""` feature seed, which also matches the label of
a real two-quote value, so `trace_application_feature` combined
`fetch('')` with `fetch('""')`. Emit no label (`null`) for empty values;
the exact value stays in the identity and properties.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:11:51 -07:00
N0zoM1z0 ce73c3fed2 refactor: compose investigation record ownership (#845) 2026-10-07 12:10:45 +08:00
Iwakurakaoru0822andClaude Opus 5.5 430c297ca4 fix(native): report exact plist integers beyond the JSON number range
`inspect_plist` parsed plutil JSON with `JSON.parse`, silently rounding
integers outside ±(2^53 - 1): `18446744073709551615` became
`18446744073709552000` with no limitation. Keep the exact decimal text
from the JSON source as `{ "$plist_type": "integer", "decimal": "..." }`
and add a limitation. On the XML fallback path, the decoder has already
rounded such values, so they become `decimal: null` instead of a wrong
number.

Also restore the `` escape in the BOM regex, which an earlier
rewrite had turned into a raw invisible character.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:04:47 -07:00
Kaoru0822 bc2cd8b874 Merge pull request #841 from morluto/fix/plist-non-json-values
fix(native): inspect plists containing data, dates, and non-finite reals
2026-10-06 21:01:10 -07:00
Iwakurakaoru0822andClaude Opus 5.5 63012eeb60 fix(javascript): keep exact empty values in graph identities
#839 displayed empty artifact-local keys and source-map original names as
`""` inside node identities, so `fetch("")` and `fetch('""')` (or
`sources: ["", "\"\""]`) produced the same node ID and merged two
distinct facts. Function nodes likewise exposed only a display label, so
`['']()` and `['""']()` were indistinguishable.

Admit the exact empty string in `artifact-local-key.key` and
`source-map-original.original_source`, keep the `""` substitution for
labels only, and record each function node's exact `name` in its
properties. Regenerate the catalog digests for the relaxed output schema.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:00:57 -07:00
Kaoru0822 e7cbfe04fd Merge pull request #839 from morluto/fix/empty-literal-graph-labels
fix(javascript): analyze sources containing empty string literals
2026-10-06 20:55:11 -07:00
Kaoru0822 522c2d0ecb Merge pull request #836 from morluto/fix/empty-static-key-consumers
fix(javascript): keep exact empty env keys and method names
2026-10-06 20:54:50 -07:00
Iwakurakaoru0822andClaude Opus 5.5 5ead2cfbc4 fix(native): inspect plists containing data, dates, and non-finite reals
`inspect_plist` converted every plist with `plutil -convert json`, which
rejects plists containing `<data>`, `<date>`, or non-finite `<real>`
values. Such valid plists (including Stocks.app's Info.plist) failed with
a cause-free `execution_failure`.

When the JSON conversion exits nonzero, decode `plutil -convert xml1`
instead. Data and dates use the `$plist_type` objects the keyed-archive
reader already emits; non-finite reals become an explicit unknown because
the XML decoder reports NaN and infinity alike. Provenance records both
conversions and limitations explain the representation. Plists that JSON
can express keep the unchanged single-conversion path.

The projection moves to `src/domain/plistValue.ts` and is shared with the
keyed-archive reader, which keeps rejecting non-finite reals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:54:23 -07:00
Kaoru0822 3a4a63f70a Merge pull request #835 from kaoru0822-kitauji/fix/electron-computed-member-keys
fix(javascript): preserve computed Electron member uncertainty
2026-10-06 20:51:31 -07:00
Iwakurakaoru0822andClaude Opus 5.5 58ef8ac3aa fix(javascript): analyze source maps with empty source names
A source map whose `sources` contains `""` (a legal relative reference,
emitted for virtual or generated modules) made the whole application
analysis fail: the empty name became the `source-map-original` identity's
`original_source`, which must be nonempty. Display it as `""` at the same
accumulator seam; the observation's `properties.source` keeps the exact
empty name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:47:27 -07:00
N0zoM1z0 be3cfbffdf fix(mcp): isolate optional observation adapter failures (#838) 2026-10-07 11:45:17 +08:00
Iwakurakaoru0822andClaude Opus 5.5 11fc3b9815 fix(javascript): analyze sources containing empty string literals
A single legal empty literal such as `fetch('')`, `require('')`,
`bus.on('', f)`, `localStorage.getItem('')`, or `ipcMain.handle('', f)`
made the whole application analysis fail with `unreadable_output`: the
literal became an application-graph observation label, an artifact-local
identity key, or a semantic node label, all of which must be nonempty.

Normalize display at the two graph construction seams instead of at each
producer: `JavaScriptArtifactGraphAccumulator.addNode` and
`constructSemanticGraphNode` show the empty value as `""` via a shared
`javascriptDisplayText` helper. Observation and node properties keep the
exact empty value. This replaces the per-site `semanticNameLabel` calls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:43:08 -07:00
morluto 78f4848d70 refactor(domain): map validation taxonomies and add inventory Result seam (#833)
Document the three disjoint failure taxonomies (filesystem reader
codes, session reference reasons, inventory TypeErrors) with a test
pinning their disjointness. Export ParsedInventorySet and add
tryAssembleInventorySet covering the empty-pages leaf as Result;
the throwing entry contract is unchanged until callers migrate.
2026-10-07 11:40:34 +08:00
morluto c13c9d41f8 refactor(domain): converge comparison mechanics on shared vocabulary (#824)
Delete the private canonicalJson duplicate in
functionComparisonNormalization in favor of comparisonSemantics
(same canonicalize behavior via the context parameter).
Add comparisonStatus as the single owner of the canonical
unchanged/changed/unknown triple and conclusion vocabulary, with
mappers pinning every pipeline-native status; adopt the shared
triple schema where wire-identical (bundle result, scenario
overall/step). Native detail enums and collation choices stay
untouched.
2026-10-07 11:40:24 +08:00
Iwakurakaoru0822andClaude Opus 5.5 ad1f6b508f fix(javascript): keep exact empty require paths and request fields
Migrate the remaining `""`-sentinel consumers from #783 to the nullable
`semanticStaticPropertyKey`: CommonJS module origins
(`require("m")['']`), require destructuring (`const {'': a} =
require("m")`), and request body fields (`{ '': value }`). Dynamic keys
still produce no link or field. API selectors that compare against known
names are unchanged.

Fixes #783

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:38:11 -07:00
Iwakurakaoru0822andClaude Opus 5.5 f7954a8fd6 fix(javascript): keep exact empty env keys and method names
`process.env['']` now projects an exact empty environment key with
complete resolution instead of the same null/partial result as a dynamic
`process.env[key]`. `{ ['']() {} }` keeps its exact empty method name in
the IR instead of a generated `[computed@N]` name.

Semantic graph labels stay nonempty: a shared `semanticNameLabel` helper
displays the empty key as `""` for property slots, config sources, and
function nodes, while `properties.key` keeps the exact value.

Refs #783

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:35:02 -07:00
morluto de9593ad48 refactor(browser): align inspector exclusions with canonical vocabulary (#834)
Report canonical BrowserExclusionReasons from runtime location
authorization (unsupported_url, not_approved) and collapse them
onto the fixed V8 wire bucket via inspectorExclusionKey, keeping
describeInspectorTargetLimitations text stable. Document the
provider authority split (attach-only CDP/V8 vs owned-runtime
Playwright) so the shared vocabulary is not re-split.
2026-10-07 11:34:57 +08:00