* fix(contracts)!: require absolute local paths for remaining caller-supplied file inputs
Follow-up to the session snapshot/export tightening: the same invisible server-cwd resolution applied to open_binary target paths (parseBinaryTarget(path, process.cwd())), import_evidence_bundle bundle reads, firmware input files (resolve(raw)), browser executable launch paths (resolve-then-spawn), Electron executable/application/root paths (realpath on raw input), and the expected server path check.
Each field gains the shared isAbsoluteLocalPath refinement plus a catalog-visible description, since JSON Schema cannot express the rule. Examples, scenario fixtures, and contract tests updated to absolute paths; new schema cases cover rejection/acceptance/omission per field.
Explicitly unchanged (verified rooted or out of scope): inspect_plist paths (resolved against the target bundle dir), firmware output_directory (already provider-enforced), filesystem observation paths (resolved against the caller-supplied working_directory), keyed-archive member paths (archive-relative), JS evidence member paths (evidence-relative under root_alias), provider-internal execution schemas, CLI-only doctor flows, and CLI options (own resolve against the operator cwd).
* fix(cli): resolve operator-relative paths before shared absolute-path validation
The contract tightening rejects relative paths, but three CLI commands forward operator-relative input into the shared schemas: firmware commands pass raw args to FirmwareAnalysisService, and the Electron/browser scenario commands validate parsed scenario JSON directly. CLI paths are relative to the operator shell, so resolve them against the working directory first: resolve() in firmwareCommands, and a shared resolveCliJsonPaths JSON key-path helper (cliJsonInput) applied in electronCommands and cliBrowserScenarioCommands. MCP behavior is unchanged — MCP callers must still send absolute paths.
Covers the regression with a relative-path firmware CLI acceptance test (asserts provider-stage capability_unavailable, not a validation error) and unit tests for the helper.
fix(contracts): require absolute local paths for session filesystem inputs
Snapshot, evidence-bundle export, and managed-target inputs accepted any non-empty string, so relative paths were resolved against the MCP server working directory instead of the caller's intent. Refine these contract fields to absolute host paths (Windows drive and forward-slash forms included), advertise the constraint on the property descriptions, and regenerate the derived catalog, product catalog, and skill catalog digest. Relative CLI options are unaffected because CLI flows do not parse these MCP contracts.
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
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>
* perf(graph): avoid repeated traversal edge scans and copies
* fix(android)!: preserve JVM settings and reuse metadata sessions
Read class metadata without generating application source, retain immutable serialized APK sessions, and join owned cleanup on cancellation and shutdown.
BREAKING CHANGE: Android analysis now requires a full JDK 17 or newer with its compiler module for the packaged Java source bridge.
A field that changed from a decodable to an undecoded signature was
reported as removed on the decoded side and unknown on the other. The
undecoded member with the same declared type and name may be that field
with a changed signature, so its decoded counterpart is now unknown too,
with a counterpart-signature-not-decoded limitation.
The compare_managed_members description now names the exact declared
type, name, and raw signature tier and the undecoded handling.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser): trace captured website module imports
Compose verified exported scripts, inert native import syntax and a narrow
Chromium resolution port. Preserve query/fragment identity, import-map context,
all reported capture candidates and explicit unknown execution. Share named
CLI/MCP contracts and retain native reports, diagnostics and cleanup failures.
Add focused boundary regressions and a real module-loading oracle to the
existing conditional Chrome lane. No captured application code is executed
by module tracing, and no selected website asset is refetched.
Refs #851, #774
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* fix(browser): preserve module contexts and source bindings
Keep capture completeness inline, validate actual source text against its
digest, and separate unsupported URL contexts from malformed input.
Use the importer origin for native module resolution and the selected map
base independently, including mixed HTTP/HTTPS and escaped HTML attributes.
Refs #851, #774
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
`swift-demangle` parsed a symbol beginning with `-` as an option, so
`-help` replaced the results with usage text and the call failed as
unreadable output. A symbol containing a line feed split into extra
output records, and the CRLF-tolerant parser stripped a carriage return
that belonged to the final symbol.
Pass the symbols after `--`, split records on the LF the demangler
emits, and reject multi-line symbols in the shared CLI/MCP input schema.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* 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>
* 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)
* 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>
* feat(web): export captured scripts for JavaScript application analysis
Add capture adapters, conservative source path projection, verified exclusive publication and a shared CLI/MCP workflow. Retain source identities, missing content and competing URL versions in a complete manifest for existing static analysis.
Refs: #774Closes: #799
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* test(web): include script export in independent effect audit
Register the new contract family in the independent inventory audit and verify the filesystem, session, network and idempotence metadata of the named export contract.
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* fix(web): preserve capture limitation values in export manifests
Align the export boundary with passive capture’s string contract instead of rejecting an admitted empty limitation. Cover the publisher boundary and regenerate canonical schemas and identities.
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* feat(browser): capture correlated network content and lifecycle evidence
Keep request identities and redirect relationships across ordered scenario events.
Capture selected browser-exposed bytes and duplicate headers through modular
readers, settle bounded reads before cleanup, and preserve unavailable states.
Keep content-selection mismatches and legacy network coverage unknown during
comparison. Verify real CLI/MCP, installed package, and browser lifecycle paths.
Refs #774
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* fix(browser): align capture defaults and redact encoded media metadata
Correct the complete documented request and legacy default expectation caught by CI. Cover and redact encoded declared values in captured body media types.
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* test(browser): verify polling capture cutoff completeness
Accept incomplete event coverage only when the continuously polling fixture has explicit unfinished requests; retain failures for other missing or truncated sections. Include actual completeness and unfinished transactions in diagnostics.
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* feat(ghidra): edit function annotations atomically
Return annotation readback and refreshed function analysis through CLI and MCP. Own each database transaction, invalidate caches and immutable snapshots, preserve executable bytes, and retain the Windows mutation boundary.
Assisted-by: Nitori (gensokyo-skills:nitori-reverse-engineering)
* fix(ghidra): preserve qualified function annotation identity
Preserve namespaces during local name writes and match qualified readback to the refreshed dossier. Add a producer-shaped regression and verify a real namespaced C++ function through the CLI.
Assisted-by: Nitori (gensokyo-skills:nitori-reverse-engineering)
* test(ghidra): align verification with annotation authority
Keep strict capability and profile checks while admitting the explicit session metadata operation. Verify packaged transport authority and atomic transaction commitments and preserve a read-only Windows expectation.
Assisted-by: Nitori (gensokyo-skills:nitori-reverse-engineering)
* feat(ghidra): admit explicit DOS COM analysis
Carry caller-selected COM interpretation through CLI, MCP and target
identity, seed real-mode entry/context before Ghidra analysis, and verify
complete loaded bytes, source mappings and measured register context.
Keep original binaries unchanged and PSP/runtime coverage explicit.
Assisted-by: Nitori (gensokyo-skills:nitori-reverse-engineering)
* fix(verification): validate COM package selection before allocating fixtures
* feat(ghidra): verify DOS load images and expose memory evidence
Verify measured source bytes, mapped regions, fixups and entries against
the immutable MZ snapshot, retaining independent checks and raw evidence.
Expose loaded byte reads and authoritative original file offsets through
both CLI and MCP, with focused and actual Ghidra DOS verification.
Assisted-by: Nitori (gensokyo-skills:nitori-reverse-engineering)
* fix(cli): describe memory inspection arguments
* test(ghidra): align bridge fixtures and CLI capability accounting
* chore(deps): finish toolchain upgrades and drop dead weight
pino 9 to 10, @types/node 24 to 26, oxlint 1.73 to 1.87, knip 6.26
to 6.39, turbo 2.10 to 2.11. Narrow engines to supported majors
(22/24/26; vitest 5 refuses Node 25). Scope no-var-requires off for
Electron CJS hooks and fixtures.
Remove TypeDoc: incompatible with TypeScript 7 at install and
runtime, used by nothing in any gate. Drop the dep, docs:api
workflow, typedoc.json, CI artifact step, and related docs.
Replace graphology with a local call-graph adjacency plus BFS: the
only consumer is call-path search, and graphology-types ships no
types entry for TS7 NodeNext resolution. Delete both graphology
dependencies.
Remove dead re-exports newly flagged by knip 6.39.
* chore: drop stale typedoc and replay references
Remove the docs:api release-checklist step, the orphaned docs/api
ignore entry, and the nonexistent replay glob from the adapters
project.
Move official, enhanced, and session contract arrays with their
builders into officialToolContracts, enhancedToolContracts, and
sessionToolContracts. toolContracts keeps the ordered assembly and
resolver. Migrate all importers including catalog scripts. No
re-export shims; generated catalog output is unchanged.
* refactor(domain): consolidate canonical ordering and digest helpers
Single owner for code-point ordering (domain/canonicalOrdering.ts)
and canonical JSON digests (domain/comparisonSemantics.ts). Delete
all local compareCodePoints/compareText/digestCanonical duplicates
and migrate every importer. No re-export shims.
* fix(ci): allow slower real browser startup
## Changes
Related to #545 and the permission-system removal in #555.
- Upgrade the shipped skill to v24 and remove obsolete filesystem grants, per-call approval flags, Electron file-root configuration, and DMG approval flags. Calls follow the user-requested investigation directly. Keep setup plan confirmation, actual OS requirements, and process/archive lifecycle boundaries.
- Correct the passive browser guide: endpoint/scope come from requests; ordinary local URL queries are retained, while credentials remain redacted.
- Audit canonical tool effects: declare possible DMG process/temp-directory effects, mark fresh extraction non-idempotent, and mark comparisons of supplied captures/PNGs as closed-world. Align artifact-provider capability effects with temporary mount-directory writes.
- Retain non-read-only hints for calls that add Evidence to the session; document that annotations are hints and that clients control their confirmation UI. Do not mislabel session mutations as read-only to suppress prompts.
- Regenerate package, skill, MCP, and product metadata from source.
## Verification
- `npm run test:focused -- <11 affected test files>`: **40 tests passed**, including skill transaction/backup/idempotence, SDK tools/list annotations, actual local capture/PNG comparisons, artifact extraction/containment/cancellation, DMG launcher/cleanup seam, setup confirmation, browser MCP and scenario MCP, CLI catalog parity.
- `npm run check`: typecheck, lint, format, knip, package metadata.
- `npm run docs:check`: generated catalogs, skill metadata, documentation facts, completion ledger, error schema.
No local real Hopper/Ghidra run: their adapters and analysis operations are unchanged. Native macOS DMG behavior is covered locally through the launcher seam; no local macOS/hdiutil claim is made.
Real browser verification passed using existing Headless Chrome143.0.7499.4: actual CLI/stdio MCP,9,331,407-byte PNG, passive capture/source maps, and owned/external scenario cleanup. An initial full Chrome143 run failed the existing screenshot-height assertion (1397 versus1536); the dedicated headless-shell run passed the complete verifier without code changes. The verifier run-lineage field remained unavailable; no lineage-coverage claim is made. Browser download into `.codex` was blocked by CDN403, so the successful run used an existing browser without changing host configuration.
* fix(comparisons)!: preserve unknowns across partial observations
Share absence and digest semantics, keep unobserved managed bodies unknown, and match unique managed type/name/signatures before structural fallback.
BREAKING CHANGE: Managed comparison metadata adds exact-signature matching and its count, and name_matching now reports exact-signature-fallback.
* fix(javascript): preserve projected result binding semantics
Share syntax-aware property reads and assigned-result resolution. Retain destructuring paths and downgrade downstream whole-result relationships instead of resolving nested or wrapped calls as aliases.
* fix(native)!: admit complete parser values and preserve typed failures
Decode Mach headers by named columns, validate complete slice keys and lipo alignment, and preserve codesign runtime flags and tagged parser errors. Rename the Ghidra test dossier fixture and connect fake-backed suites to real verification lanes.
BREAKING CHANGE: Native load-command results no longer contain the unused, always-null file_offset field.
* fix(process): preserve host identity and actionable boundary failures
Thread selected platform and environment through process and Doctor seams, stamp observed producer identity in Evidence, and retain PTY, filesystem, lease and lazy-provider failure causes. Drain cancelled lazy loads and omit exited descendants from verified lineage.
* fix(browser): preserve cleanup and document-transition evidence
Make V8 and Playwright teardown cancellation-aware, expose primary failures alongside incomplete cleanup, share frame-tree and navigation rules, and clear stale WebMCP registrations without pruning unrelated child frames.
* fix(adapters): align managed targets and typed CLI outcomes
Inspect managed PE/CLI targets independently of native provider selection, reuse successful managed selections, and keep evidence bound to the actual inspected target. Classify canonical CLI error envelopes and exhaustive setup/update/uninstall outcomes, audit registered CLI coverage, and assert platform-specific runtime results.
* docs: refresh boundary contracts and shipped roadmap behavior
Return complete canonical Evidence records inline, including normalized_result, and preserve direct comparison and retained bundle identity.
Verified full deterministic gate, real Linux Ghidra CLI/MCP and independently installed artifact, generic package acceptance, private local samples, and targeted updates after syncing main.
Closes#551
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Correlate typed labels with recovered block entries and one indirect dispatch.
Preserve ambiguous and nonexact integer associations as unknown with raw diagnostics.
Expose defaults separately, collect backing load metadata, and invalidate old profiles.
Add independent compiler-byte CLI/MCP acceptance and actual Ghidra model controls.
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
* fix(hopper): report unavailable procedure body coverage
* refactor!: simplify runtime tools and remove replay engines
Keep direct inspection, capture, and comparison tools. Bind handlers to named contracts and let agents compose experiments with commands and local fixture servers.
BREAKING CHANGE: Remove controlled replay, Node characterization, finite replay-machine, managed runtime planning, and redundant string-tracing tools. Retire process replay, shims, reactive scenarios, custom checkpoints, and active browser replay and origin-scope inputs.
Validate DOS MZ load modules and import them with Ghidra's 16-bit
real-mode profile. Preserve complete observed inclusive function body
ranges through inventory, function analysis, Evidence and snapshots.
Add a public source-generated DOS CLI/MCP verification lane and
regressions for malformed headers, body membership and cache profiles.
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
Keep explicitly selected Node Inspector targets observable when discovery
cannot verify their file location. Resolve literal POSIX discovery paths
without URI decoding, and retain lossy Windows or underscore paths as
unresolved metadata. Validate scriptParsed file URLs independently.
Preserve unknown target identity through runtime reconciliation, regenerate
contracts, and verify real CLI/MCP behavior on Linux and Windows.
Closes#530
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)