From 5aa23c3d17456e331d6df2866490b81577e04e32 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Tue, 27 Oct 2026 13:06:57 +0800 Subject: [PATCH] refactor(providers): move inspection scope to application --- docs/architecture.mermaid | 4 ++-- scripts/verify/architecture-guards.mjs | 7 +++++++ src/application/AnalysisProvider.ts | 2 +- src/{providers => application}/ProviderInspectionScope.ts | 0 src/application/binary/AnalysisProviderRegistry.ts | 2 +- src/ghidra/GhidraProvider.behavior.test.ts | 2 +- src/ghidra/GhidraProvider.ts | 2 +- src/ida/IdaNativeProtocol.test.ts | 2 +- src/ida/IdaProvider.ts | 2 +- 9 files changed, 15 insertions(+), 8 deletions(-) rename src/{providers => application}/ProviderInspectionScope.ts (100%) diff --git a/docs/architecture.mermaid b/docs/architecture.mermaid index 015b835ecb..91603c944e 100644 --- a/docs/architecture.mermaid +++ b/docs/architecture.mermaid @@ -21,14 +21,14 @@ graph TD subgraph "Application Layer" APP["src/application/
Shared CLI/MCP workflows
enhanced analysis and investigations"] SESSION["SessionProviderRouter + BinarySession
one immutable deep binding per target
disjoint auxiliary routing"] - REGISTRY["AnalysisProviderRegistry
sorted deep candidates
deterministic selection, no fallback"] + REGISTRY["AnalysisProviderRegistry
sorted deep candidates
deterministic selection, no fallback
ProviderInspectionScope: prerequisite observation lifetime"] RECORDS["src/application/investigation/
composed InvestigationRecords + narrow ports
EvidenceLedger and Unknown ownership"] SNAPSHOT["BinarySessionRecords + AnalysisSnapshotCache
binary target/profile snapshots and session file ownership
record coordination and post-commit notifications"] JS_RECON["src/application/javascript/ + src/artifacts/javascript/
JavaScript artifact reconstruction
directory/ASAR reads
AST-only bundle projection"] end subgraph "Provider Layers (selected adapters)" - PROVIDER_OWNERS["src/providers/
shared deferred client and inspection owners
exact cleanup retry and attributed failures"] + PROVIDER_OWNERS["src/providers/
shared deferred client owners
exact cleanup retry and attributed failures"] PWNTOOLS["src/native/pwntools/ + src/native/pwndbg/
BYO offline ELF/core adapters
owned snapshots/Python and optional core-only GDB
unchanged upstream parsers, ABI structures and mapping API"] WASM["src/wasm/
caller-supplied WABT; immutable artifact inspection
owned process supervision and retryable workspace cleanup"] APKSIG["src/apkSignature/
in-process APK Signing Block + v1 reader
bounded single read, no device or execution"] diff --git a/scripts/verify/architecture-guards.mjs b/scripts/verify/architecture-guards.mjs index 78a3958e53..1aad503f91 100644 --- a/scripts/verify/architecture-guards.mjs +++ b/scripts/verify/architecture-guards.mjs @@ -59,6 +59,13 @@ const check = (label, selected, pattern, allow = []) => { ); }; +// Prerequisite inspection lifetime is an application contract shared by adapters. +check( + "provider-owned inspection lifetime (use src/application/ProviderInspectionScope)", + files, + /providers\/ProviderInspectionScope\.js/, +); + check( "src/domain uses localeCompare (use compareUnicodeCodePoints)", inDir("src/domain/"), diff --git a/src/application/AnalysisProvider.ts b/src/application/AnalysisProvider.ts index b216afa1f8..5a06c5c79b 100644 --- a/src/application/AnalysisProvider.ts +++ b/src/application/AnalysisProvider.ts @@ -1,5 +1,5 @@ import type { AnalysisObservation } from "../domain/analysisObservation.js"; -import type { ProviderInspectionScope } from "../providers/ProviderInspectionScope.js"; +import type { ProviderInspectionScope } from "./ProviderInspectionScope.js"; import type { BinaryTarget } from "../domain/binaryTargetTypes.js"; import type { OfficialToolName } from "../contracts/officialToolContracts.js"; import type { EnhancedToolName } from "../contracts/enhancedInputs.js"; diff --git a/src/providers/ProviderInspectionScope.ts b/src/application/ProviderInspectionScope.ts similarity index 100% rename from src/providers/ProviderInspectionScope.ts rename to src/application/ProviderInspectionScope.ts diff --git a/src/application/binary/AnalysisProviderRegistry.ts b/src/application/binary/AnalysisProviderRegistry.ts index 0a61b66605..3af1805679 100644 --- a/src/application/binary/AnalysisProviderRegistry.ts +++ b/src/application/binary/AnalysisProviderRegistry.ts @@ -1,4 +1,4 @@ -import { ProviderInspectionScope } from "../../providers/ProviderInspectionScope.js"; +import { ProviderInspectionScope } from "../ProviderInspectionScope.js"; import { AnalysisCleanupLease } from "../../artifacts/AnalysisCleanupLease.js"; import { ArtifactResourceScope } from "../../artifacts/ArtifactResourceScope.js"; import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js"; diff --git a/src/ghidra/GhidraProvider.behavior.test.ts b/src/ghidra/GhidraProvider.behavior.test.ts index c822407db4..911f280a7b 100644 --- a/src/ghidra/GhidraProvider.behavior.test.ts +++ b/src/ghidra/GhidraProvider.behavior.test.ts @@ -4,7 +4,7 @@ import { GhidraNativeAotSnapshotOwner } from "./GhidraNativeAotSnapshotOwner.js" import { AnalysisCleanupLease } from "../artifacts/AnalysisCleanupLease.js"; import { resolvedAnalysisError } from "../domain/analysisErrorBase.js"; import { createDeferred } from "../../tests/fixtures/binarySession.js"; -import { ProviderInspectionScope } from "../providers/ProviderInspectionScope.js"; +import { ProviderInspectionScope } from "../application/ProviderInspectionScope.js"; import { ok as javaProbeOk, err, ok } from "../domain/result.js"; import type { GhidraJavaObservation } from "./GhidraJavaProbe.js"; import type { GhidraSeedReport } from "./GhidraAnalysisSeeds.js"; diff --git a/src/ghidra/GhidraProvider.ts b/src/ghidra/GhidraProvider.ts index cfccece9c3..e032ba2683 100644 --- a/src/ghidra/GhidraProvider.ts +++ b/src/ghidra/GhidraProvider.ts @@ -6,7 +6,7 @@ import { import { ProviderAdapterError } from "../domain/providerAdapterError.js"; import { resolveGhidraProject } from "./GhidraProjectSnapshot.js"; import { DeferredAnalysisClient } from "../providers/DeferredAnalysisClient.js"; -import type { ProviderInspectionScope } from "../providers/ProviderInspectionScope.js"; +import type { ProviderInspectionScope } from "../application/ProviderInspectionScope.js"; import { analysisClientFailureForOperation } from "../providers/AnalysisClientFailure.js"; import { AnalysisCleanupLease } from "../artifacts/AnalysisCleanupLease.js"; import { diff --git a/src/ida/IdaNativeProtocol.test.ts b/src/ida/IdaNativeProtocol.test.ts index 7e6cfbf516..e8194cbb5e 100644 --- a/src/ida/IdaNativeProtocol.test.ts +++ b/src/ida/IdaNativeProtocol.test.ts @@ -26,7 +26,7 @@ import type { RetainedResourceScope, AnalysisProfileResolution, } from "../application/AnalysisProvider.js"; -import { ProviderInspectionScope } from "../providers/ProviderInspectionScope.js"; +import { ProviderInspectionScope } from "../application/ProviderInspectionScope.js"; import type { AnalysisProfileCommitment } from "../domain/analysisProfile.js"; const resourceScope: RetainedResourceScope = { diff --git a/src/ida/IdaProvider.ts b/src/ida/IdaProvider.ts index 7a308a758a..44bb1509e1 100644 --- a/src/ida/IdaProvider.ts +++ b/src/ida/IdaProvider.ts @@ -50,7 +50,7 @@ import { privateRuntimeRootCapability } from "../process/PrivateRuntimeRoot.js"; import { ArtifactResourceScope } from "../artifacts/ArtifactResourceScope.js"; import { AnalysisCleanupLease } from "../artifacts/AnalysisCleanupLease.js"; import { ProviderCleanupError } from "../domain/providerCleanupError.js"; -import type { ProviderInspectionScope } from "../providers/ProviderInspectionScope.js"; +import type { ProviderInspectionScope } from "../application/ProviderInspectionScope.js"; /** Bring-your-own IDA MCP candidate; discovery performs no provider startup. */ export class IdaProvider implements AnalysisProviderCandidate {