rea-agents 1.7.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -59
- package/bridge/ghidra/ReaGhidraBridge.java +96 -11
- package/dist/application/ArtifactExtraction.js +1 -1
- package/dist/application/ArtifactInventory/classify.js +42 -0
- package/dist/application/ArtifactInventory/hash.js +43 -0
- package/dist/application/ArtifactInventory/reader.js +41 -0
- package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
- package/dist/application/ArtifactInventory/scanReader.js +124 -0
- package/dist/application/ArtifactInventory/types.js +10 -0
- package/dist/application/ArtifactInventory.js +9 -351
- package/dist/application/AuthorizedArtifactInventory.js +2 -2
- package/dist/application/BinarySession.js +47 -270
- package/dist/application/BinarySessionExecution.js +28 -0
- package/dist/application/BinarySessionOpen.js +39 -0
- package/dist/application/BinarySessionRecords.js +149 -0
- package/dist/application/BinarySessionStatus.js +75 -0
- package/dist/application/CapabilityInventory.js +42 -2
- package/dist/application/ClientRegistrationStatus.js +1 -1
- package/dist/application/CrossVersionInventory.js +8 -2
- package/dist/application/CrossVersionInvestigation.js +11 -29
- package/dist/application/CrossVersionInvestigationCollections.js +23 -0
- package/dist/application/DirectAnalysis.js +47 -44
- package/dist/application/Doctor.js +165 -197
- package/dist/application/DoctorDiagnostics.js +180 -0
- package/dist/application/ElectronBoundaryAnalysis.js +112 -0
- package/dist/application/ElectronBoundaryGraph.js +9 -0
- package/dist/application/ElectronBoundaryGraphContext.js +62 -0
- package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
- package/dist/application/ElectronBoundaryGraphNative.js +86 -0
- package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
- package/dist/application/EnhancedToolPagination.js +22 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +58 -50
- package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
- package/dist/application/InvestigationProviders.js +30 -0
- package/dist/application/InvestigationWorkspaceStore.js +24 -10
- package/dist/application/JavaScriptApplicationEvidence.js +26 -0
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
- package/dist/application/JavaScriptApplicationService.js +74 -0
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
- package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
- package/dist/application/JavaScriptArtifactFiles.js +6 -2
- package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
- package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
- package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
- package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
- package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
- package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
- package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
- package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
- package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
- package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
- package/dist/application/JavaScriptJsonModules.js +39 -0
- package/dist/application/JavaScriptModuleRelationships.js +262 -0
- package/dist/application/JavaScriptReplayPermission.js +16 -0
- package/dist/application/JavaScriptReplayPlanning.js +201 -0
- package/dist/application/JavaScriptReplayService.js +292 -0
- package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
- package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
- package/dist/application/LinuxHopper.js +10 -0
- package/dist/application/MacHopper.js +22 -11
- package/dist/application/ManagedApplicationGraphService.js +55 -0
- package/dist/application/ManagedMemberComparisonService.js +122 -0
- package/dist/application/ManagedNativeVerificationService.js +39 -0
- package/dist/application/ManagedReconstructionService.js +58 -0
- package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
- package/dist/application/PermissionAuthority.js +106 -63
- package/dist/application/ProcessCaptureCapability.js +1 -1
- package/dist/application/ProcessCapturePermission.js +13 -0
- package/dist/application/ProcessCli.js +2 -12
- package/dist/application/ProcessHarness.js +1 -1
- package/dist/application/ProcessSampling.js +15 -11
- package/dist/application/ProjectPermissionStore.js +49 -9
- package/dist/application/RealHopperAssertions.js +76 -0
- package/dist/application/ReconstructionCoverageService.js +69 -0
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
- package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
- package/dist/application/Setup.js +147 -259
- package/dist/application/SetupClientConfiguration.js +220 -0
- package/dist/application/SetupClients.js +24 -2
- package/dist/application/SetupPlan.js +123 -12
- package/dist/application/SetupSkill.js +26 -12
- package/dist/application/SupportedClients.js +1 -0
- package/dist/application/Uninstall.js +6 -3
- package/dist/application/WindowsCapabilities.js +86 -0
- package/dist/application/runtime.js +2 -0
- package/dist/artifacts/AsarArtifactReader.js +11 -0
- package/dist/browser/BrowserProcessStartup.js +88 -0
- package/dist/browser/CdpCaptureDocuments.js +12 -8
- package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
- package/dist/browser/CdpCaptureEventHandlers.js +336 -0
- package/dist/browser/CdpCaptureEventHelpers.js +71 -0
- package/dist/browser/CdpCaptureEventState.js +1 -0
- package/dist/browser/CdpCaptureEventTypes.js +1 -0
- package/dist/browser/CdpCaptureEvents.js +46 -464
- package/dist/browser/CdpElectronInspection.js +106 -162
- package/dist/browser/CdpElectronProvider.js +5 -1
- package/dist/browser/CdpElectronScriptEvents.js +69 -0
- package/dist/browser/CdpElectronScripts.js +94 -0
- package/dist/browser/CdpElectronWorkers.js +56 -0
- package/dist/browser/CdpObservationSession.js +51 -8
- package/dist/browser/CdpPageCapture.js +12 -129
- package/dist/browser/CdpPageCaptureScripts.js +97 -0
- package/dist/browser/CdpPageCaptureWorkers.js +46 -0
- package/dist/browser/CdpWebMcpDiscovery.js +38 -14
- package/dist/browser/PngVisualDiff.js +9 -2
- package/dist/catalogIdentity.js +8 -1
- package/dist/cli/artifactCommands.js +82 -0
- package/dist/cli/coreAnalysisCommands.js +232 -0
- package/dist/cli/managedCommands.js +397 -0
- package/dist/cli/managedProjectGraphCommand.js +24 -0
- package/dist/cli/options.js +9 -0
- package/dist/cli/setupCommands.js +108 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +122 -0
- package/dist/cli.js +13 -383
- package/dist/cliApplicationCommands.js +176 -0
- package/dist/cliBrowserAdvancedCommands.js +73 -16
- package/dist/cliBrowserCommands.js +39 -115
- package/dist/cliCommandNames.js +17 -0
- package/dist/cliElectronCommands.js +100 -27
- package/dist/cliEvidenceCommands.js +13 -2
- package/dist/cliInvestigationCommands.js +53 -10
- package/dist/cliJsonInput.js +54 -0
- package/dist/cliObservationOptions.js +137 -0
- package/dist/cliPolicyCommands.js +80 -46
- package/dist/cliSetup.js +289 -0
- package/dist/config/environment.js +107 -0
- package/dist/config/parseConfig.js +228 -0
- package/dist/config/parsers.js +68 -0
- package/dist/config/permissions.js +30 -0
- package/dist/config/types.js +1 -0
- package/dist/config.js +1 -292
- package/dist/contracts/applicationToolContracts.js +225 -0
- package/dist/contracts/artifactToolContracts.js +5 -9
- package/dist/contracts/browserToolContracts.js +14 -62
- package/dist/contracts/electronToolContracts.js +45 -19
- package/dist/contracts/errorSchemas.js +1 -0
- package/dist/contracts/investigationExamples.js +0 -6
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
- package/dist/contracts/managedToolContracts.js +153 -0
- package/dist/contracts/managedWorkflowExamples.js +346 -0
- package/dist/contracts/managedWorkflowToolContracts.js +203 -0
- package/dist/contracts/nativeToolContracts.js +2 -6
- package/dist/contracts/promptContracts.js +18 -2
- package/dist/contracts/providerSelection.js +2 -0
- package/dist/contracts/toolContractExamples.js +10 -25
- package/dist/contracts/toolContracts.js +49 -47
- package/dist/contracts/toolEffects.js +174 -0
- package/dist/contracts/toolOutputSchemaGroups.js +232 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
- package/dist/contracts/toolOutputSchemas.js +2 -535
- package/dist/doctorRuntime.js +42 -1
- package/dist/domain/analysisErrorPresentation.js +234 -0
- package/dist/domain/analysisErrorProjection.js +284 -0
- package/dist/domain/artifactComparison.js +37 -19
- package/dist/domain/binaryTarget.js +87 -37
- package/dist/domain/browserObservation.js +1 -282
- package/dist/domain/browserObservationSchemas.js +286 -0
- package/dist/domain/bundleComparison.js +4 -4
- package/dist/domain/electronObservation.js +13 -0
- package/dist/domain/electronStaticAnalysis.js +9 -0
- package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
- package/dist/domain/electronStaticAnalysisIpc.js +171 -0
- package/dist/domain/electronStaticAnalysisNative.js +164 -0
- package/dist/domain/electronStaticAnalysisTypes.js +1 -0
- package/dist/domain/electronStaticAnalysisValues.js +103 -0
- package/dist/domain/errors.js +32 -448
- package/dist/domain/functionComparison.js +4 -165
- package/dist/domain/functionComparisonDimensions.js +164 -0
- package/dist/domain/functionComparisonSchemas.js +3 -8
- package/dist/domain/inputIssueProjection.js +52 -0
- package/dist/domain/javascriptApplicationAnalysis.js +155 -0
- package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
- package/dist/domain/javascriptApplicationGraph.js +2 -1
- package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
- package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
- package/dist/domain/javascriptApplicationVersionItems.js +233 -0
- package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
- package/dist/domain/javascriptExportInstrumentation.js +97 -0
- package/dist/domain/javascriptFeatureSeed.js +140 -0
- package/dist/domain/javascriptFeatureTrace.js +232 -0
- package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
- package/dist/domain/javascriptFeatureTraversal.js +100 -0
- package/dist/domain/javascriptNativeHandoff.js +85 -0
- package/dist/domain/javascriptReplay.js +361 -0
- package/dist/domain/javascriptRuntimeLoadState.js +106 -0
- package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
- package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
- package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
- package/dist/domain/javascriptSemanticAnalysis.js +386 -0
- package/dist/domain/javascriptSemanticIr.js +30 -0
- package/dist/domain/javascriptSemanticProjection.js +366 -0
- package/dist/domain/javascriptSemanticState.js +40 -0
- package/dist/domain/javascriptSemanticTraversal.js +22 -0
- package/dist/domain/javascriptSemanticValues.js +352 -0
- package/dist/domain/javascriptStaticAnalysis.js +26 -254
- package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
- package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
- package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
- package/dist/domain/javascriptStaticAnalysisState.js +6 -0
- package/dist/domain/knownPageCoverage.js +21 -0
- package/dist/domain/managedApplicationGraph.js +206 -0
- package/dist/domain/managedApplicationGraphCoverage.js +170 -0
- package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
- package/dist/domain/managedApplicationGraphNodes.js +336 -0
- package/dist/domain/managedArtifact.js +452 -0
- package/dist/domain/managedMemberComparison.js +211 -0
- package/dist/domain/managedMemberComparisonCoverage.js +72 -0
- package/dist/domain/managedMemberComparisonMatch.js +356 -0
- package/dist/domain/managedNativeVerification.js +46 -0
- package/dist/domain/managedNativeVerificationMatch.js +272 -0
- package/dist/domain/managedNativeVerificationSchemas.js +141 -0
- package/dist/domain/managedReconstruction.js +196 -0
- package/dist/domain/managedRuntimeCorrelation.js +184 -0
- package/dist/domain/nodeRuntimeCharacterization.js +66 -0
- package/dist/domain/permissionPolicy.js +2 -0
- package/dist/domain/reconstructionCoverage.js +387 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
- package/dist/domain/reconstructionVerificationSchemas.js +9 -3
- package/dist/domain/runtimeCharacterization.js +85 -0
- package/dist/domain/webBundleAnalyzer.js +3 -409
- package/dist/domain/webBundleAnalyzerAst.js +77 -0
- package/dist/domain/webBundleAnalyzerInspection.js +307 -0
- package/dist/domain/webBundleAnalyzerResult.js +120 -0
- package/dist/dotnet/ManagedArtifactInspector.js +339 -0
- package/dist/dotnet/ManagedMemberInspector.js +153 -0
- package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
- package/dist/dotnet/ManagedMemberRows.js +120 -0
- package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
- package/dist/dotnet/ManagedMetadataInventory.js +104 -0
- package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
- package/dist/dotnet/ManagedMetadataLayout.js +259 -0
- package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
- package/dist/dotnet/ManagedPeReader.js +188 -0
- package/dist/dotnet/ManagedReaderFailure.js +10 -0
- package/dist/dotnet/ManagedStaticProvider.js +203 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraClient.js +76 -91
- package/dist/ghidra/GhidraClientStartup.js +29 -0
- package/dist/ghidra/GhidraClientWire.js +34 -0
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraDiagnostics.js +6 -1
- package/dist/ghidra/GhidraInstallation.js +20 -15
- package/dist/ghidra/GhidraLauncher.js +93 -29
- package/dist/ghidra/GhidraProvider.js +67 -161
- package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
- package/dist/ghidra/GhidraSessionValues.js +2 -0
- package/dist/ghidra/GhidraSocketConnection.js +44 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
- package/dist/ghidra/GhidraTransport.js +71 -0
- package/dist/identity.js +3 -2
- package/dist/main/messages.js +5 -0
- package/dist/main/reload.js +49 -0
- package/dist/main/shutdown.js +25 -0
- package/dist/main/startup.js +14 -0
- package/dist/main/state.js +26 -0
- package/dist/main/transport.js +61 -0
- package/dist/main/types.js +1 -0
- package/dist/main.js +35 -132
- package/dist/process/PrivateRuntimeRoot.js +3 -2
- package/dist/process/ProcessOwnership.js +35 -0
- package/dist/process/ProviderProcess.js +2 -0
- package/dist/replay/JavaScriptReplayWorker.js +300 -0
- package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
- package/dist/replay/LinuxRuntimeClosure.js +46 -0
- package/dist/replay/LinuxSeccompPolicy.js +40 -0
- package/dist/replay/ReplayOutcome.js +95 -0
- package/dist/replay/ReplayProcessLifecycle.js +71 -0
- package/dist/replay/ReplayWorkerProtocol.js +55 -0
- package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
- package/dist/server/ProcessCaptureElicitation.js +157 -0
- package/dist/server/createServer.js +158 -41
- package/dist/server/registerApplicationTools/characterization.js +57 -0
- package/dist/server/registerApplicationTools/compareVersions.js +34 -0
- package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
- package/dist/server/registerApplicationTools/coverage.js +84 -0
- package/dist/server/registerApplicationTools/helpers.js +42 -0
- package/dist/server/registerApplicationTools/traceFeature.js +26 -0
- package/dist/server/registerApplicationTools/types.js +1 -0
- package/dist/server/registerApplicationTools.js +13 -0
- package/dist/server/registerArtifactComparisonTool.js +16 -9
- package/dist/server/registerBrowserTools.js +61 -60
- package/dist/server/registerBundleComparisonTool.js +17 -20
- package/dist/server/registerElectronTools.js +39 -12
- package/dist/server/registerEnhancedTools.js +52 -15
- package/dist/server/registerEvidenceResources.js +54 -0
- package/dist/server/registerEvidenceTools.js +5 -1
- package/dist/server/registerFunctionComparisonTool.js +14 -7
- package/dist/server/registerInvestigationTools/helpers.js +74 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +103 -132
- package/dist/server/registerManagedTools.js +6 -0
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
- package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
- package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
- package/dist/server/registerManagedWorkflowTools/types.js +1 -0
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
- package/dist/server/registerManagedWorkflowTools.js +13 -0
- package/dist/server/registerOfficialTools.js +81 -67
- package/dist/server/registerProcessComparisonTool.js +25 -47
- package/dist/server/registerSessionRecordTools.js +137 -0
- package/dist/server/registerSessionStatusTool.js +9 -8
- package/dist/server/registerSessionTools.js +77 -216
- package/dist/server/sessionAvailabilityPolicy.js +10 -0
- package/dist/server/sessionEvidence.js +14 -19
- package/dist/server/toolInputValidation.js +77 -0
- package/dist/server/toolRegistrationOptions.js +177 -2
- package/dist/server/toolResult.js +30 -17
- package/package.json +21 -14
- package/scripts/rea.mjs +1 -1
- package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
- package/scripts/prepare-node-pty.mjs +0 -35
- package/scripts/rebuild-native.mjs +0 -22
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { EnhancedTools } from "../application/EnhancedTools.js";
|
|
2
|
-
import { enhancedToolNameSchema } from "../contracts/enhancedInputs.js";
|
|
1
|
+
import { EnhancedTools, } from "../application/EnhancedTools.js";
|
|
2
|
+
import { enhancedInputSchemas, enhancedToolNameSchema, } from "../contracts/enhancedInputs.js";
|
|
3
3
|
import { ENHANCED_TOOL_CONTRACTS, } from "../contracts/toolContracts.js";
|
|
4
4
|
import { toCallToolResult } from "./toolResult.js";
|
|
5
5
|
import { logToolExecution } from "./toolLogging.js";
|
|
6
6
|
import { createEvidence } from "../domain/evidence.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { UnknownRegistryError } from "../domain/errors.js";
|
|
7
|
+
import { AnalysisInputError, UnknownRegistryError } from "../domain/errors.js";
|
|
8
|
+
import { ok } from "../domain/result.js";
|
|
10
9
|
import { mcpProgressReporter } from "./mcpProgress.js";
|
|
11
10
|
import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "../application/InvestigationProviders.js";
|
|
11
|
+
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
|
12
|
+
import { safeParseToolInput } from "./toolInputValidation.js";
|
|
12
13
|
/** Register composed workflows against the same port as direct bridge tools. */
|
|
13
14
|
export const registerEnhancedTools = (server, analysis, options) => {
|
|
14
15
|
const services = new EnhancedTools(analysis);
|
|
@@ -24,12 +25,7 @@ export const registerEnhancedTools = (server, analysis, options) => {
|
|
|
24
25
|
};
|
|
25
26
|
const registerEnhancedTool = (server, services, contract, registration) => {
|
|
26
27
|
const name = enhancedToolNameSchema.parse(contract.name);
|
|
27
|
-
server.registerTool(name, {
|
|
28
|
-
description: contract.description,
|
|
29
|
-
inputSchema: contract.inputSchema,
|
|
30
|
-
outputSchema: contract.outputSchema,
|
|
31
|
-
annotations: contract.annotations,
|
|
32
|
-
}, async (input, context) => {
|
|
28
|
+
server.registerTool(name, toolRegistrationOptions(contract), async (input, context) => {
|
|
33
29
|
const progress = mcpProgressReporter(context);
|
|
34
30
|
await progress.report({
|
|
35
31
|
phase: name,
|
|
@@ -37,9 +33,12 @@ const registerEnhancedTool = (server, services, contract, registration) => {
|
|
|
37
33
|
total: 1,
|
|
38
34
|
message: "started",
|
|
39
35
|
});
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
const validatedCall = parseEnhancedCall(name, input);
|
|
37
|
+
if (!validatedCall.ok)
|
|
38
|
+
return toCallToolResult(validatedCall, contract);
|
|
39
|
+
const parsedInput = validatedCall.value.input;
|
|
40
|
+
const parameters = jsonParameters(parsedInput);
|
|
41
|
+
const result = await logToolExecution(registration.logger, name, () => services.executeValidated(validatedCall.value, context.mcpReq.signal));
|
|
43
42
|
await progress.report({
|
|
44
43
|
phase: name,
|
|
45
44
|
completed: 1,
|
|
@@ -68,7 +67,7 @@ const registerEnhancedTool = (server, services, contract, registration) => {
|
|
|
68
67
|
return toCallToolResult(recorded, contract);
|
|
69
68
|
const unknowns = recordWorkflowUnknowns({
|
|
70
69
|
name,
|
|
71
|
-
input:
|
|
70
|
+
input: parameters,
|
|
72
71
|
result: result.value,
|
|
73
72
|
evidenceId: evidence.evidence_id,
|
|
74
73
|
recordUnknown: registration.recordUnknown,
|
|
@@ -82,6 +81,44 @@ const registerEnhancedTool = (server, services, contract, registration) => {
|
|
|
82
81
|
return toCallToolResult(result, contract);
|
|
83
82
|
});
|
|
84
83
|
};
|
|
84
|
+
const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
|
|
85
|
+
const ENHANCED_INPUT_PARSERS = {
|
|
86
|
+
swift_classes: (input) => safeParseToolInput(enhancedInputSchemas.swift_classes, input, "swift_classes"),
|
|
87
|
+
get_objc_classes: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_classes, input, "get_objc_classes"),
|
|
88
|
+
get_objc_protocols: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_protocols, input, "get_objc_protocols"),
|
|
89
|
+
batch_decompile: (input) => safeParseToolInput(enhancedInputSchemas.batch_decompile, input, "batch_decompile"),
|
|
90
|
+
get_call_graph: (input) => safeParseToolInput(enhancedInputSchemas.get_call_graph, input, "get_call_graph"),
|
|
91
|
+
analyze_swift_types: (input) => safeParseToolInput(enhancedInputSchemas.analyze_swift_types, input, "analyze_swift_types"),
|
|
92
|
+
find_xrefs_to_name: (input) => safeParseToolInput(enhancedInputSchemas.find_xrefs_to_name, input, "find_xrefs_to_name"),
|
|
93
|
+
binary_overview: (input) => safeParseToolInput(enhancedInputSchemas.binary_overview, input, "binary_overview"),
|
|
94
|
+
analyze_function: (input) => safeParseToolInput(enhancedInputSchemas.analyze_function, input, "analyze_function"),
|
|
95
|
+
trace_feature: (input) => safeParseToolInput(enhancedInputSchemas.trace_feature, input, "trace_feature"),
|
|
96
|
+
};
|
|
97
|
+
const parseEnhancedCall = (name, input) => {
|
|
98
|
+
switch (name) {
|
|
99
|
+
case "swift_classes":
|
|
100
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.swift_classes(input), (value) => ({ name, input: value }));
|
|
101
|
+
case "get_objc_classes":
|
|
102
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_classes(input), (value) => ({ name, input: value }));
|
|
103
|
+
case "get_objc_protocols":
|
|
104
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_protocols(input), (value) => ({ name, input: value }));
|
|
105
|
+
case "batch_decompile":
|
|
106
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.batch_decompile(input), (value) => ({ name, input: value }));
|
|
107
|
+
case "get_call_graph":
|
|
108
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_call_graph(input), (value) => ({ name, input: value }));
|
|
109
|
+
case "analyze_swift_types":
|
|
110
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_swift_types(input), (value) => ({ name, input: value }));
|
|
111
|
+
case "find_xrefs_to_name":
|
|
112
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.find_xrefs_to_name(input), (value) => ({ name, input: value }));
|
|
113
|
+
case "binary_overview":
|
|
114
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.binary_overview(input), (value) => ({ name, input: value }));
|
|
115
|
+
case "analyze_function":
|
|
116
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_function(input), (value) => ({ name, input: value }));
|
|
117
|
+
case "trace_feature":
|
|
118
|
+
return mapEnhancedCall(ENHANCED_INPUT_PARSERS.trace_feature(input), (value) => ({ name, input: value }));
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const mapEnhancedCall = (parsed, project) => parsed.ok ? ok(project(parsed.value)) : parsed;
|
|
85
122
|
const recordWorkflowUnknowns = ({ name, input, result, evidenceId, recordUnknown, }) => {
|
|
86
123
|
if (name !== "trace_feature" ||
|
|
87
124
|
input.unknown_registry_approved !== true ||
|
|
@@ -4,6 +4,45 @@ import canonicalize from "canonicalize";
|
|
|
4
4
|
const evidenceUri = (evidenceId) => `rea://evidence/${evidenceId}`;
|
|
5
5
|
/** Expose immutable session-owned Evidence v2 records as MCP resources. */
|
|
6
6
|
export const registerEvidenceResources = (server, session) => {
|
|
7
|
+
registerReconstructionCoverageResource(server, session);
|
|
8
|
+
registerInvestigationWorkspaceResource(server, session);
|
|
9
|
+
registerSessionEvidenceResource(server, session);
|
|
10
|
+
registerActiveResidualUnknownsResource(server, session);
|
|
11
|
+
registerAnalysisSnapshotResource(server, session);
|
|
12
|
+
registerArtifactPageResource(server, session);
|
|
13
|
+
registerFunctionDossierResource(server, session);
|
|
14
|
+
registerEvidenceSectionResource(server, session);
|
|
15
|
+
registerResidualUnknownResource(server, session);
|
|
16
|
+
};
|
|
17
|
+
const registerReconstructionCoverageResource = (server, session) => {
|
|
18
|
+
server.registerResource("reconstruction-coverage-revision", new ResourceTemplate("rea://reconstruction-coverage/{workspaceId}/revision/{revision}", {
|
|
19
|
+
list: () => ({
|
|
20
|
+
resources: session
|
|
21
|
+
.reconstructionCoverageWorkspaces()
|
|
22
|
+
.map((workspace) => ({
|
|
23
|
+
uri: coverageWorkspaceUri(workspace.workspace_id, workspace.revision),
|
|
24
|
+
name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
|
|
25
|
+
title: `${workspace.name} coverage revision ${String(workspace.revision)}`,
|
|
26
|
+
description: "Immutable evidence-backed reconstruction coverage workspace revision.",
|
|
27
|
+
mimeType: "application/json",
|
|
28
|
+
})),
|
|
29
|
+
}),
|
|
30
|
+
}), {
|
|
31
|
+
title: "Reconstruction coverage revision",
|
|
32
|
+
description: "Canonical CAS-linked surfaces, owners, claims, verifiers, evidence, and completion boundaries.",
|
|
33
|
+
mimeType: "application/json",
|
|
34
|
+
}, (uri, variables) => {
|
|
35
|
+
const workspaceId = stringVariable(variables.workspaceId, uri.href);
|
|
36
|
+
const revisionText = stringVariable(variables.revision, uri.href);
|
|
37
|
+
if (!/^\d+$/u.test(revisionText))
|
|
38
|
+
throw new ResourceNotFoundError(uri.href);
|
|
39
|
+
const workspace = session.reconstructionCoverageWorkspace(workspaceId, Number(revisionText));
|
|
40
|
+
if (workspace === undefined)
|
|
41
|
+
throw new ResourceNotFoundError(uri.href);
|
|
42
|
+
return jsonResource(uri.href, workspace);
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
const registerInvestigationWorkspaceResource = (server, session) => {
|
|
7
46
|
server.registerResource("investigation-workspace-revision", new ResourceTemplate("rea://workspace/{workspaceId}/revision/{revision}", {
|
|
8
47
|
list: () => ({
|
|
9
48
|
resources: session.investigationWorkspaces().map((workspace) => ({
|
|
@@ -40,6 +79,8 @@ export const registerEvidenceResources = (server, session) => {
|
|
|
40
79
|
throw new ResourceNotFoundError(uri.href);
|
|
41
80
|
return jsonResource(uri.href, workspace);
|
|
42
81
|
});
|
|
82
|
+
};
|
|
83
|
+
const registerSessionEvidenceResource = (server, session) => {
|
|
43
84
|
server.registerResource("session-evidence", new ResourceTemplate("rea://evidence/{evidenceId}", {
|
|
44
85
|
list: () => ({
|
|
45
86
|
resources: session.exportEvidenceBundle().records.map((evidence) => ({
|
|
@@ -77,11 +118,15 @@ export const registerEvidenceResources = (server, session) => {
|
|
|
77
118
|
],
|
|
78
119
|
};
|
|
79
120
|
});
|
|
121
|
+
};
|
|
122
|
+
const registerActiveResidualUnknownsResource = (server, session) => {
|
|
80
123
|
server.registerResource("active-residual-unknowns", "rea://unknowns/active", {
|
|
81
124
|
title: "Active residual unknowns",
|
|
82
125
|
description: "Current unresolved session-owned residual unknown heads.",
|
|
83
126
|
mimeType: "application/json",
|
|
84
127
|
}, (uri) => jsonResource(uri.href, session.listUnknowns().filter(({ status }) => status !== "resolved")));
|
|
128
|
+
};
|
|
129
|
+
const registerAnalysisSnapshotResource = (server, session) => {
|
|
85
130
|
server.registerResource("analysis-snapshot", new ResourceTemplate("rea://snapshot/{snapshotDigest}", {
|
|
86
131
|
list: () => {
|
|
87
132
|
const snapshot = session.exportAnalysisSnapshot();
|
|
@@ -111,6 +156,8 @@ export const registerEvidenceResources = (server, session) => {
|
|
|
111
156
|
throw new ResourceNotFoundError(uri.href);
|
|
112
157
|
return jsonResource(uri.href, snapshot.value);
|
|
113
158
|
});
|
|
159
|
+
};
|
|
160
|
+
const registerArtifactPageResource = (server, session) => {
|
|
114
161
|
server.registerResource("artifact-page", new ResourceTemplate("rea://artifact/{manifestId}/{collection}", {
|
|
115
162
|
list: undefined,
|
|
116
163
|
complete: {
|
|
@@ -143,6 +190,8 @@ export const registerEvidenceResources = (server, session) => {
|
|
|
143
190
|
limitations: evidence.limitations,
|
|
144
191
|
});
|
|
145
192
|
});
|
|
193
|
+
};
|
|
194
|
+
const registerFunctionDossierResource = (server, session) => {
|
|
146
195
|
server.registerResource("function-dossier", new ResourceTemplate("rea://function/{targetSha256}/{address}", {
|
|
147
196
|
list: undefined,
|
|
148
197
|
}), {
|
|
@@ -161,6 +210,8 @@ export const registerEvidenceResources = (server, session) => {
|
|
|
161
210
|
throw new ResourceNotFoundError(uri.href);
|
|
162
211
|
return jsonResource(uri.href, evidence);
|
|
163
212
|
});
|
|
213
|
+
};
|
|
214
|
+
const registerEvidenceSectionResource = (server, session) => {
|
|
164
215
|
server.registerResource("evidence-section", new ResourceTemplate("rea://evidence/{evidenceId}/section/{section}", {
|
|
165
216
|
list: undefined,
|
|
166
217
|
complete: {
|
|
@@ -191,6 +242,8 @@ export const registerEvidenceResources = (server, session) => {
|
|
|
191
242
|
value,
|
|
192
243
|
});
|
|
193
244
|
});
|
|
245
|
+
};
|
|
246
|
+
const registerResidualUnknownResource = (server, session) => {
|
|
194
247
|
server.registerResource("residual-unknown", new ResourceTemplate("rea://unknown/{unknownId}", {
|
|
195
248
|
list: () => ({
|
|
196
249
|
resources: session.listUnknowns().map((unknown) => ({
|
|
@@ -224,6 +277,7 @@ export const registerEvidenceResources = (server, session) => {
|
|
|
224
277
|
return jsonResource(uri.href, { current: unknown, history });
|
|
225
278
|
});
|
|
226
279
|
};
|
|
280
|
+
const coverageWorkspaceUri = (workspaceId, revision) => `rea://reconstruction-coverage/${workspaceId}/revision/${String(revision)}`;
|
|
227
281
|
const workspaceUri = (workspaceId, revision) => `rea://workspace/${workspaceId}/revision/${String(revision)}`;
|
|
228
282
|
const EVIDENCE_SECTIONS = [
|
|
229
283
|
"result",
|
|
@@ -4,6 +4,7 @@ import { logToolExecution } from "./toolLogging.js";
|
|
|
4
4
|
import { toCallToolResult } from "./toolResult.js";
|
|
5
5
|
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
|
6
6
|
import { mcpProgressReporter } from "./mcpProgress.js";
|
|
7
|
+
import { safeParseToolInput } from "./toolInputValidation.js";
|
|
7
8
|
import { AnalysisProtocolError, PermissionRequiredError, } from "../domain/errors.js";
|
|
8
9
|
import { err } from "../domain/result.js";
|
|
9
10
|
/** Register provider-backed contracts that return atomic Evidence v2 observations. */
|
|
@@ -17,7 +18,10 @@ export const registerEvidenceTools = (server, analysis, contracts, options) => {
|
|
|
17
18
|
total: 1,
|
|
18
19
|
message: "started",
|
|
19
20
|
});
|
|
20
|
-
const
|
|
21
|
+
const parsedInput = safeParseToolInput(contract.inputSchema, input, contract.name);
|
|
22
|
+
if (!parsedInput.ok)
|
|
23
|
+
return toCallToolResult(parsedInput, contract);
|
|
24
|
+
const parameters = jsonObjectSchema.parse(parsedInput.value);
|
|
21
25
|
if (options.permissionAuthority !== undefined) {
|
|
22
26
|
const request = permissionRequest(contract.name, parameters);
|
|
23
27
|
if (request !== undefined) {
|
|
@@ -4,21 +4,29 @@ import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
|
4
4
|
import { FUNCTION_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
|
|
5
5
|
import { toCallToolResult } from "./toolResult.js";
|
|
6
6
|
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
|
|
7
|
-
import {
|
|
7
|
+
import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
|
|
8
8
|
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
|
9
9
|
import { runDerivedOperation } from "./runDerivedOperation.js";
|
|
10
|
+
import { safeParseToolInput } from "./toolInputValidation.js";
|
|
10
11
|
/** Register explicit Evidence-backed function comparison. */
|
|
11
12
|
export const registerFunctionComparisonTool = (server, session, contract) => {
|
|
12
13
|
server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
|
|
13
|
-
const
|
|
14
|
-
|
|
14
|
+
const parsedInput = safeParseToolInput(functionComparisonInputSchema, input, contract.name);
|
|
15
|
+
if (!parsedInput.ok)
|
|
16
|
+
return toCallToolResult(parsedInput, contract);
|
|
17
|
+
const parsed = parsedInput.value;
|
|
18
|
+
const expected = {
|
|
19
|
+
operation: "analyze_function",
|
|
20
|
+
predicate: "rea.analysis/v2",
|
|
21
|
+
};
|
|
22
|
+
const left = resolveSessionEvidenceIds(session, parsed.left_evidence_ids, expected);
|
|
15
23
|
if (!left.ok)
|
|
16
24
|
return toCallToolResult(left, contract);
|
|
17
|
-
const right =
|
|
25
|
+
const right = resolveSessionEvidenceIds(session, parsed.right_evidence_ids, expected);
|
|
18
26
|
if (!right.ok)
|
|
19
27
|
return toCallToolResult(right, contract);
|
|
20
|
-
const leftIds =
|
|
21
|
-
const rightIds =
|
|
28
|
+
const leftIds = left.value.map(({ evidence_id: id }) => id);
|
|
29
|
+
const rightIds = right.value.map(({ evidence_id: id }) => id);
|
|
22
30
|
const computed = await runDerivedOperation(context, contract.name, () => compareFunctions(left.value, right.value, parsed.offset, parsed.limit));
|
|
23
31
|
if (!computed.ok)
|
|
24
32
|
return toCallToolResult(computed, contract);
|
|
@@ -69,4 +77,3 @@ const functionUnknownInput = ({ approved, status, leftIds, rightIds, }) => {
|
|
|
69
77
|
relationships: [],
|
|
70
78
|
};
|
|
71
79
|
};
|
|
72
|
-
const evidenceIds = (input) => (Array.isArray(input) ? input : [input]).map(({ evidence_id: id }) => id);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { EvidenceIntegrityError, } from "../../domain/errors.js";
|
|
2
|
+
import { err, ok } from "../../domain/result.js";
|
|
3
|
+
import { recordDerivedEvidence } from "../recordDerivedEvidence.js";
|
|
4
|
+
import { evaluateReconstructionClosure } from "../../domain/reconstructionCoverage.js";
|
|
5
|
+
import { AnalysisInputError } from "../../domain/errors.js";
|
|
6
|
+
/** Build the execution context passed to cross-version investigation. */
|
|
7
|
+
export const investigationContext = ({ session, signal, inputRoots, integrityContinueEnabled, progress, }) => ({
|
|
8
|
+
session,
|
|
9
|
+
signal,
|
|
10
|
+
inputRoots,
|
|
11
|
+
integrityContinueEnabled,
|
|
12
|
+
...(progress === undefined ? {} : { progress }),
|
|
13
|
+
});
|
|
14
|
+
export const isIncomplete = (status) => status === "unknown" || status === "truncated";
|
|
15
|
+
export const comparisonClosure = (comparisons) => uniqueIds(comparisons.flatMap((evidence) => [
|
|
16
|
+
evidence.evidence_id,
|
|
17
|
+
...evidence.evidence_links,
|
|
18
|
+
]));
|
|
19
|
+
export const functionEvidenceIds = (groups) => uniqueIds(groups.flatMap((group) => (Array.isArray(group) ? group : [group]).map(({ evidence_id: id }) => id)));
|
|
20
|
+
const uniqueIds = (ids) => [...new Set(ids)].sort((left, right) => left.localeCompare(right));
|
|
21
|
+
export const evidenceClosure = (session, seedIds) => {
|
|
22
|
+
const records = new Map(session
|
|
23
|
+
.exportEvidenceBundle()
|
|
24
|
+
.records.map((evidence) => [evidence.evidence_id, evidence]));
|
|
25
|
+
const visited = new Set();
|
|
26
|
+
const pending = [...seedIds];
|
|
27
|
+
while (pending.length > 0) {
|
|
28
|
+
const evidenceId = pending.pop();
|
|
29
|
+
if (evidenceId === undefined || visited.has(evidenceId))
|
|
30
|
+
continue;
|
|
31
|
+
const evidence = records.get(evidenceId);
|
|
32
|
+
if (evidence === undefined)
|
|
33
|
+
return err(new EvidenceIntegrityError("Investigation input has a dangling Evidence link"));
|
|
34
|
+
visited.add(evidenceId);
|
|
35
|
+
pending.push(...evidence.evidence_links);
|
|
36
|
+
}
|
|
37
|
+
return ok(uniqueIds([...visited]));
|
|
38
|
+
};
|
|
39
|
+
/** Verify a retained coverage boundary before reconstruction evidence is derived. */
|
|
40
|
+
export const verifyCoverageReadiness = (session, coverage) => {
|
|
41
|
+
if (coverage === undefined)
|
|
42
|
+
return ok(null);
|
|
43
|
+
const workspace = session.reconstructionCoverageWorkspace(coverage.workspace_id, coverage.revision);
|
|
44
|
+
if (workspace === undefined ||
|
|
45
|
+
workspace.revision_sha256 !== coverage.revision_sha256)
|
|
46
|
+
return err(new EvidenceIntegrityError("The requested reconstruction coverage revision is not retained by this session"));
|
|
47
|
+
try {
|
|
48
|
+
const result = evaluateReconstructionClosure(workspace, coverage.boundary_id, Date.now());
|
|
49
|
+
return result.status === "ready"
|
|
50
|
+
? ok(null)
|
|
51
|
+
: err(new EvidenceIntegrityError(`Reconstruction coverage boundary is ${result.status}; readiness requires ready`));
|
|
52
|
+
}
|
|
53
|
+
catch (cause) {
|
|
54
|
+
return err(new AnalysisInputError("verify_reconstruction", { cause }));
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
export const recordWorkflowEvidence = (...[session, evidence, approved, unresolved, input]) => {
|
|
58
|
+
if (approved !== true || !unresolved) {
|
|
59
|
+
return recordDerivedEvidence(session, evidence, undefined);
|
|
60
|
+
}
|
|
61
|
+
return recordDerivedEvidence(session, evidence, {
|
|
62
|
+
approved: true,
|
|
63
|
+
question: input.question,
|
|
64
|
+
severity: "high",
|
|
65
|
+
domain: input.domain,
|
|
66
|
+
supporting_evidence_ids: [evidence.evidence_id],
|
|
67
|
+
contradicting_evidence_ids: [],
|
|
68
|
+
required_authority: input.requiredAuthority,
|
|
69
|
+
required_confidence: input.requiredConfidence,
|
|
70
|
+
required_environment: null,
|
|
71
|
+
recommended_probes: [...input.probes],
|
|
72
|
+
relationships: [],
|
|
73
|
+
});
|
|
74
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { runCrossVersionInvestigationValidated } from "../application/CrossVersionInvestigation.js";
|
|
2
|
+
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
|
3
|
+
import { safeParseToolInput } from "./toolInputValidation.js";
|
|
2
4
|
import { buildCallPath, callPathInputSchema } from "../domain/callPath.js";
|
|
3
5
|
import { correlateStaticAndRuntime, staticRuntimeCorrelationInputSchema, } from "../domain/staticRuntimeCorrelation.js";
|
|
4
6
|
import { reconstructionVerificationInputSchema, verifyReconstruction, } from "../domain/reconstructionVerification.js";
|
|
5
7
|
import { changedBehaviorResultSchema, changedBehaviorInputSchema, findChangedBehavior, } from "../domain/changedBehavior.js";
|
|
6
8
|
import { createEvidence } from "../domain/evidence.js";
|
|
7
|
-
import {
|
|
9
|
+
import {} from "../domain/errors.js";
|
|
8
10
|
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
9
|
-
import { err, ok } from "../domain/result.js";
|
|
10
11
|
import { CALL_PATH_PROVIDER, CHANGED_BEHAVIOR_PROVIDER, RECONSTRUCTION_PROVIDER, STATIC_RUNTIME_PROVIDER, } from "./sessionToolPolicies.js";
|
|
11
12
|
import { toCallToolResult } from "./toolResult.js";
|
|
12
|
-
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
|
|
13
13
|
import { mcpProgressReporter } from "./mcpProgress.js";
|
|
14
|
-
import { runDerivedOperation } from "./runDerivedOperation.js";
|
|
14
|
+
import { runDerivedOperation, } from "./runDerivedOperation.js";
|
|
15
15
|
import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "../application/DeferredFileAuthorization.js";
|
|
16
|
+
import { comparisonClosure, evidenceClosure, functionEvidenceIds, investigationContext, isIncomplete, recordWorkflowEvidence, verifyCoverageReadiness, } from "./registerInvestigationTools/helpers.js";
|
|
16
17
|
/** Register Evidence-composed differential investigation workflows. */
|
|
17
18
|
export const registerInvestigationTools = (server, session, contracts, policies) => {
|
|
18
19
|
registerChangedBehavior(server, session, contracts[0], policies);
|
|
@@ -20,81 +21,23 @@ export const registerInvestigationTools = (server, session, contracts, policies)
|
|
|
20
21
|
registerStaticRuntime(server, session, contracts[2]);
|
|
21
22
|
registerReconstruction(server, session, contracts[3]);
|
|
22
23
|
};
|
|
23
|
-
const investigationExecution = (session, signal, inputRoots, integrityContinueEnabled, progress) => ({
|
|
24
|
-
session,
|
|
25
|
-
signal,
|
|
26
|
-
inputRoots,
|
|
27
|
-
integrityContinueEnabled,
|
|
28
|
-
...(progress === undefined ? {} : { progress }),
|
|
29
|
-
});
|
|
30
|
-
const isIncomplete = (status) => status === "unknown" || status === "truncated";
|
|
31
24
|
const registerChangedBehavior = (server, session, contract, policies) => {
|
|
32
25
|
server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
|
|
33
|
-
const
|
|
26
|
+
const parsedInput = safeParseToolInput(changedBehaviorInputSchema, input, contract.name);
|
|
27
|
+
if (!parsedInput.ok)
|
|
28
|
+
return toCallToolResult(parsedInput, contract);
|
|
29
|
+
const parsed = parsedInput.value;
|
|
34
30
|
const investigationRun = parsed.investigation_run;
|
|
35
|
-
if (investigationRun !== undefined)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
writeCapability: "investigation_workspace_write",
|
|
45
|
-
operation: contract.name,
|
|
46
|
-
});
|
|
47
|
-
if (!authorizedWorkspace.ok)
|
|
48
|
-
return toCallToolResult(authorizedWorkspace, contract);
|
|
49
|
-
workspaceAuthorization = authorizedWorkspace.value;
|
|
50
|
-
authorizeInputRead = () => authorizeRootPermission(authority, {
|
|
51
|
-
capability: "investigation_input",
|
|
52
|
-
roots: [investigationRun.left_path, investigationRun.right_path],
|
|
53
|
-
access: "read",
|
|
54
|
-
operation: contract.name,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
const investigated = await runCrossVersionInvestigation(investigationRun, policies.evidenceFiles, {
|
|
58
|
-
...investigationExecution(session, context.mcpReq.signal, policies.inputRoots, policies.integrityContinueEnabled?.() ?? false, progress),
|
|
59
|
-
...(workspaceAuthorization === undefined
|
|
60
|
-
? {}
|
|
61
|
-
: {
|
|
62
|
-
authorizeWorkspaceWrite: workspaceAuthorization.authorizeWrite,
|
|
63
|
-
}),
|
|
64
|
-
...(authorizeInputRead === undefined ? {} : { authorizeInputRead }),
|
|
31
|
+
if (investigationRun !== undefined)
|
|
32
|
+
return runAutomaticInvestigation({
|
|
33
|
+
server,
|
|
34
|
+
session,
|
|
35
|
+
contract,
|
|
36
|
+
policies,
|
|
37
|
+
investigationRun,
|
|
38
|
+
unknownRegistryApproved: parsed.unknown_registry_approved,
|
|
39
|
+
context,
|
|
65
40
|
});
|
|
66
|
-
if (!investigated.ok)
|
|
67
|
-
return toCallToolResult(investigated, contract);
|
|
68
|
-
const workspace = investigated.value.workspace;
|
|
69
|
-
if (session.retainInvestigationWorkspace(workspace) === "added")
|
|
70
|
-
server.sendResourceListChanged();
|
|
71
|
-
const result = changedBehaviorResultSchema.parse(investigated.value.evidence.normalized_result);
|
|
72
|
-
const toolResult = toCallToolResult(recordWorkflowEvidence(session, investigated.value.evidence, parsed.unknown_registry_approved, isIncomplete(result.behavior_status), {
|
|
73
|
-
question: `Automatic changed behavior run ${result.investigation_run?.run_id ?? "unknown"} remains ${result.behavior_status}`,
|
|
74
|
-
domain: "changed-behavior",
|
|
75
|
-
requiredAuthority: "controlled-replay",
|
|
76
|
-
requiredConfidence: "observed",
|
|
77
|
-
probes: [
|
|
78
|
-
{
|
|
79
|
-
operation: "capture_process_scenario",
|
|
80
|
-
rationale: "Capture both versions under the same bounded scenario and environment.",
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
}), contract);
|
|
84
|
-
return {
|
|
85
|
-
...toolResult,
|
|
86
|
-
content: [
|
|
87
|
-
...toolResult.content,
|
|
88
|
-
{
|
|
89
|
-
type: "resource_link",
|
|
90
|
-
uri: `rea://workspace/${workspace.workspace_id}/revision/${String(workspace.revision)}`,
|
|
91
|
-
name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
|
|
92
|
-
description: "Immutable CAS-linked investigation workspace revision",
|
|
93
|
-
mimeType: "application/json",
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
41
|
const closure = evidenceClosure(session, comparisonClosure(parsed.comparisons));
|
|
99
42
|
if (!closure.ok)
|
|
100
43
|
return toCallToolResult(closure, contract);
|
|
@@ -132,9 +75,80 @@ const registerChangedBehavior = (server, session, contract, policies) => {
|
|
|
132
75
|
return toCallToolResult(recorded, contract);
|
|
133
76
|
});
|
|
134
77
|
};
|
|
78
|
+
const runAutomaticInvestigation = async (input) => {
|
|
79
|
+
const { policies, investigationRun, contract, session } = input;
|
|
80
|
+
const progress = mcpProgressReporter(input.context);
|
|
81
|
+
let workspaceAuthorization;
|
|
82
|
+
let authorizeInputRead;
|
|
83
|
+
if (policies.permissionAuthority !== undefined) {
|
|
84
|
+
const authority = policies.permissionAuthority;
|
|
85
|
+
const authorizedWorkspace = await authorizeFileReadWithDeferredWrite(authority, {
|
|
86
|
+
path: investigationRun.workspace_path,
|
|
87
|
+
readCapability: "investigation_workspace_read",
|
|
88
|
+
writeCapability: "investigation_workspace_write",
|
|
89
|
+
operation: contract.name,
|
|
90
|
+
});
|
|
91
|
+
if (!authorizedWorkspace.ok)
|
|
92
|
+
return toCallToolResult(authorizedWorkspace, contract);
|
|
93
|
+
workspaceAuthorization = authorizedWorkspace.value;
|
|
94
|
+
authorizeInputRead = () => authorizeRootPermission(authority, {
|
|
95
|
+
capability: "investigation_input",
|
|
96
|
+
roots: [investigationRun.left_path, investigationRun.right_path],
|
|
97
|
+
access: "read",
|
|
98
|
+
operation: contract.name,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
const investigated = await runCrossVersionInvestigationValidated(investigationRun, policies.evidenceFiles, {
|
|
102
|
+
...investigationContext({
|
|
103
|
+
session,
|
|
104
|
+
signal: input.context.mcpReq.signal,
|
|
105
|
+
inputRoots: policies.inputRoots,
|
|
106
|
+
integrityContinueEnabled: policies.integrityContinueEnabled?.() ?? false,
|
|
107
|
+
progress,
|
|
108
|
+
}),
|
|
109
|
+
...(workspaceAuthorization === undefined
|
|
110
|
+
? {}
|
|
111
|
+
: { authorizeWorkspaceWrite: workspaceAuthorization.authorizeWrite }),
|
|
112
|
+
...(authorizeInputRead === undefined ? {} : { authorizeInputRead }),
|
|
113
|
+
});
|
|
114
|
+
if (!investigated.ok)
|
|
115
|
+
return toCallToolResult(investigated, contract);
|
|
116
|
+
const workspace = investigated.value.workspace;
|
|
117
|
+
if (session.retainInvestigationWorkspace(workspace) === "added")
|
|
118
|
+
input.server.sendResourceListChanged();
|
|
119
|
+
const result = changedBehaviorResultSchema.parse(investigated.value.evidence.normalized_result);
|
|
120
|
+
const toolResult = toCallToolResult(recordWorkflowEvidence(session, investigated.value.evidence, input.unknownRegistryApproved, isIncomplete(result.behavior_status), {
|
|
121
|
+
question: `Automatic changed behavior run ${result.investigation_run?.run_id ?? "unknown"} remains ${result.behavior_status}`,
|
|
122
|
+
domain: "changed-behavior",
|
|
123
|
+
requiredAuthority: "controlled-replay",
|
|
124
|
+
requiredConfidence: "observed",
|
|
125
|
+
probes: [
|
|
126
|
+
{
|
|
127
|
+
operation: "capture_process_scenario",
|
|
128
|
+
rationale: "Capture both versions under the same bounded scenario and environment.",
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
}), contract);
|
|
132
|
+
return {
|
|
133
|
+
...toolResult,
|
|
134
|
+
content: [
|
|
135
|
+
...toolResult.content,
|
|
136
|
+
{
|
|
137
|
+
type: "resource_link",
|
|
138
|
+
uri: `rea://workspace/${workspace.workspace_id}/revision/${String(workspace.revision)}`,
|
|
139
|
+
name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
|
|
140
|
+
description: "Immutable CAS-linked investigation workspace revision",
|
|
141
|
+
mimeType: "application/json",
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
};
|
|
145
|
+
};
|
|
135
146
|
const registerCallPath = (server, session, contract) => {
|
|
136
147
|
server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
|
|
137
|
-
const
|
|
148
|
+
const parsedInput = safeParseToolInput(callPathInputSchema, input, contract.name);
|
|
149
|
+
if (!parsedInput.ok)
|
|
150
|
+
return toCallToolResult(parsedInput, contract);
|
|
151
|
+
const parsed = parsedInput.value;
|
|
138
152
|
const closure = evidenceClosure(session, functionEvidenceIds(parsed.functions));
|
|
139
153
|
if (!closure.ok)
|
|
140
154
|
return toCallToolResult(closure, contract);
|
|
@@ -177,7 +191,10 @@ const registerCallPath = (server, session, contract) => {
|
|
|
177
191
|
};
|
|
178
192
|
const registerStaticRuntime = (server, session, contract) => {
|
|
179
193
|
server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
|
|
180
|
-
const
|
|
194
|
+
const parsedInput = safeParseToolInput(staticRuntimeCorrelationInputSchema, input, contract.name);
|
|
195
|
+
if (!parsedInput.ok)
|
|
196
|
+
return toCallToolResult(parsedInput, contract);
|
|
197
|
+
const parsed = parsedInput.value;
|
|
181
198
|
const closure = evidenceClosure(session, comparisonClosure([
|
|
182
199
|
...parsed.static_comparisons,
|
|
183
200
|
...parsed.runtime_comparisons,
|
|
@@ -219,13 +236,14 @@ const registerStaticRuntime = (server, session, contract) => {
|
|
|
219
236
|
};
|
|
220
237
|
const registerReconstruction = (server, session, contract) => {
|
|
221
238
|
server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
|
|
222
|
-
const
|
|
239
|
+
const parsedInput = safeParseToolInput(reconstructionVerificationInputSchema, input, contract.name);
|
|
240
|
+
if (!parsedInput.ok)
|
|
241
|
+
return toCallToolResult(parsedInput, contract);
|
|
242
|
+
const parsed = parsedInput.value;
|
|
243
|
+
const coverage = verifyCoverageReadiness(session, parsed.coverage);
|
|
244
|
+
if (!coverage.ok)
|
|
245
|
+
return toCallToolResult(coverage, contract);
|
|
223
246
|
const owned = session.exportEvidenceBundle();
|
|
224
|
-
const ownedUnknowns = new Set(owned.unknowns.map(({ revision_digest: digest }) => digest));
|
|
225
|
-
const ownedEvidenceIds = new Set(owned.records.map(({ evidence_id: id }) => id));
|
|
226
|
-
if (parsed.evidence_bundle.records.some(({ evidence_id: id }) => !ownedEvidenceIds.has(id)) ||
|
|
227
|
-
parsed.evidence_bundle.unknowns.some(({ revision_digest: digest }) => !ownedUnknowns.has(digest)))
|
|
228
|
-
return toCallToolResult(err(new EvidenceIntegrityError("Reconstruction input unknown history is not present in this session")), contract);
|
|
229
247
|
const computed = await runDerivedOperation(context, contract.name, () => verifyReconstruction(parsed.specification, owned, parsed.offset, parsed.limit));
|
|
230
248
|
if (!computed.ok)
|
|
231
249
|
return toCallToolResult(computed, contract);
|
|
@@ -261,51 +279,4 @@ const registerReconstruction = (server, session, contract) => {
|
|
|
261
279
|
}), contract);
|
|
262
280
|
});
|
|
263
281
|
};
|
|
264
|
-
const contractOptions =
|
|
265
|
-
description: contract.description,
|
|
266
|
-
inputSchema: contract.inputSchema,
|
|
267
|
-
outputSchema: contract.outputSchema,
|
|
268
|
-
annotations: contract.annotations,
|
|
269
|
-
});
|
|
270
|
-
const comparisonClosure = (comparisons) => uniqueIds(comparisons.flatMap((evidence) => [
|
|
271
|
-
evidence.evidence_id,
|
|
272
|
-
...evidence.evidence_links,
|
|
273
|
-
]));
|
|
274
|
-
const functionEvidenceIds = (groups) => uniqueIds(groups.flatMap((group) => (Array.isArray(group) ? group : [group]).map(({ evidence_id: id }) => id)));
|
|
275
|
-
const uniqueIds = (ids) => [...new Set(ids)].sort((left, right) => left.localeCompare(right));
|
|
276
|
-
const evidenceClosure = (session, seedIds) => {
|
|
277
|
-
const records = new Map(session
|
|
278
|
-
.exportEvidenceBundle()
|
|
279
|
-
.records.map((evidence) => [evidence.evidence_id, evidence]));
|
|
280
|
-
const visited = new Set();
|
|
281
|
-
const pending = [...seedIds];
|
|
282
|
-
while (pending.length > 0) {
|
|
283
|
-
const evidenceId = pending.pop();
|
|
284
|
-
if (evidenceId === undefined || visited.has(evidenceId))
|
|
285
|
-
continue;
|
|
286
|
-
const evidence = records.get(evidenceId);
|
|
287
|
-
if (evidence === undefined)
|
|
288
|
-
return err(new EvidenceIntegrityError("Investigation input has a dangling Evidence link"));
|
|
289
|
-
visited.add(evidenceId);
|
|
290
|
-
pending.push(...evidence.evidence_links);
|
|
291
|
-
}
|
|
292
|
-
return ok(uniqueIds([...visited]));
|
|
293
|
-
};
|
|
294
|
-
const recordWorkflowEvidence = (...[session, evidence, approved, unresolved, input]) => {
|
|
295
|
-
if (approved !== true || !unresolved) {
|
|
296
|
-
return recordDerivedEvidence(session, evidence, undefined);
|
|
297
|
-
}
|
|
298
|
-
return recordDerivedEvidence(session, evidence, {
|
|
299
|
-
approved: true,
|
|
300
|
-
question: input.question,
|
|
301
|
-
severity: "high",
|
|
302
|
-
domain: input.domain,
|
|
303
|
-
supporting_evidence_ids: [evidence.evidence_id],
|
|
304
|
-
contradicting_evidence_ids: [],
|
|
305
|
-
required_authority: input.requiredAuthority,
|
|
306
|
-
required_confidence: input.requiredConfidence,
|
|
307
|
-
required_environment: null,
|
|
308
|
-
recommended_probes: [...input.probes],
|
|
309
|
-
relationships: [],
|
|
310
|
-
});
|
|
311
|
-
};
|
|
282
|
+
const contractOptions = toolRegistrationOptions;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MANAGED_TOOL_CONTRACTS } from "../contracts/managedToolContracts.js";
|
|
2
|
+
import { registerEvidenceTools } from "./registerEvidenceTools.js";
|
|
3
|
+
/** Register execution-free managed PE/CLI inspection. */
|
|
4
|
+
export const registerManagedTools = (server, analysis, options) => {
|
|
5
|
+
registerEvidenceTools(server, analysis, MANAGED_TOOL_CONTRACTS, options);
|
|
6
|
+
};
|