rea-agents 2.0.0 → 2.2.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 +103 -38
- package/bridge/ghidra/ReaGhidraBridge.java +96 -11
- package/dist/application/AndroidApplicationService.js +17 -0
- package/dist/application/AppleApplicationService.js +17 -0
- 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 +24 -2
- package/dist/application/ClientRegistrationStatus.js +11 -4
- package/dist/application/CrossVersionInventory.js +8 -2
- package/dist/application/CrossVersionInvestigation.js +1 -23
- package/dist/application/CrossVersionInvestigationCollections.js +23 -0
- package/dist/application/DirectAnalysis.js +47 -44
- package/dist/application/Doctor.js +156 -238
- package/dist/application/DoctorDiagnostics.js +180 -0
- package/dist/application/ElectronBoundaryAnalysis.js +23 -7
- package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
- package/dist/application/EnhancedToolPagination.js +22 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +20 -37
- package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
- package/dist/application/InventoryProjectionEvidence.js +41 -0
- package/dist/application/InvestigationProviders.js +12 -0
- package/dist/application/InvestigationWorkspaceStore.js +24 -10
- package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
- package/dist/application/JavaScriptArtifactFiles.js +6 -2
- package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
- package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
- package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
- package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
- 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 +1 -1
- package/dist/application/JavaScriptJsonModules.js +39 -0
- package/dist/application/JavaScriptModuleRelationships.js +262 -0
- package/dist/application/JavaScriptReplayPermission.js +16 -0
- package/dist/application/JavaScriptReplayService.js +182 -156
- package/dist/application/LinuxHopper.js +10 -0
- package/dist/application/MacHopper.js +22 -11
- 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/ProcessPairedExperiment.js +72 -0
- package/dist/application/ProjectPermissionStore.js +48 -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 +148 -260
- package/dist/application/SetupClientConfiguration.js +224 -0
- package/dist/application/SetupClients.js +24 -2
- package/dist/application/SetupPlan.js +124 -12
- package/dist/application/SetupSkill.js +54 -36
- package/dist/application/SupportedClients.js +1 -0
- package/dist/application/Uninstall.js +12 -3
- package/dist/application/Upgrade.js +16 -1
- package/dist/application/WindowsCapabilities.js +86 -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 +29 -496
- package/dist/browser/CdpObservationSession.js +51 -8
- package/dist/browser/CdpPageCapture.js +12 -133
- 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 +4 -0
- 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 +113 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +122 -0
- package/dist/cli.js +10 -768
- package/dist/cliApplicationCommands.js +118 -4
- package/dist/cliBrowserAdvancedCommands.js +73 -16
- package/dist/cliBrowserCommands.js +39 -115
- package/dist/cliCommandNames.js +4 -0
- package/dist/cliElectronCommands.js +33 -62
- package/dist/cliEvidenceCommands.js +13 -2
- package/dist/cliInvestigationCommands.js +53 -10
- package/dist/cliObservationOptions.js +137 -0
- package/dist/cliPolicyCommands.js +80 -46
- package/dist/cliSetup.js +306 -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 -375
- package/dist/contracts/applicationToolContracts.js +134 -0
- package/dist/contracts/electronToolContracts.js +51 -3
- package/dist/contracts/managedToolContracts.js +8 -3
- package/dist/contracts/managedWorkflowToolContracts.js +3 -3
- package/dist/contracts/providerSelection.js +2 -0
- package/dist/contracts/sessionStatusContract.js +26 -0
- package/dist/contracts/toolContractTypes.js +12 -1
- package/dist/contracts/toolContracts.js +5 -12
- package/dist/contracts/toolEffects.js +14 -0
- package/dist/contracts/toolOutputSchemaGroups.js +274 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +328 -0
- package/dist/contracts/toolOutputSchemas.js +2 -550
- package/dist/domain/analysisErrorPresentation.js +234 -0
- package/dist/domain/analysisErrorProjection.js +284 -0
- package/dist/domain/androidApplication.js +206 -0
- package/dist/domain/appleApplication.js +221 -0
- package/dist/domain/artifactComparison.js +34 -15
- package/dist/domain/binaryTarget.js +87 -37
- package/dist/domain/boundedCartesianProjection.js +15 -0
- package/dist/domain/browserObservation.js +1 -285
- package/dist/domain/browserObservationSchemas.js +286 -0
- package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
- package/dist/domain/errors.js +4 -486
- package/dist/domain/functionComparison.js +4 -165
- package/dist/domain/functionComparisonDimensions.js +164 -0
- package/dist/domain/javascriptApplicationVersionItems.js +18 -6
- package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
- package/dist/domain/javascriptExportInstrumentation.js +97 -0
- package/dist/domain/javascriptFeatureTraversal.js +19 -7
- package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
- 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 +5 -221
- package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
- package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
- package/dist/domain/knownPageCoverage.js +21 -0
- package/dist/domain/managedApplicationGraph.js +14 -364
- 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 +16 -8
- package/dist/domain/managedMemberComparison.js +37 -391
- package/dist/domain/managedMemberComparisonCoverage.js +72 -0
- package/dist/domain/managedMemberComparisonMatch.js +356 -0
- package/dist/domain/managedNativeVerification.js +27 -389
- package/dist/domain/managedNativeVerificationMatch.js +272 -0
- package/dist/domain/managedNativeVerificationSchemas.js +141 -0
- package/dist/domain/managedReconstruction.js +82 -69
- package/dist/domain/managedRuntimeCorrelation.js +12 -3
- package/dist/domain/nodeRuntimeCharacterization.js +66 -0
- package/dist/domain/permissionPolicy.js +2 -0
- package/dist/domain/processComparison.js +19 -0
- package/dist/domain/processPairedExperiment.js +128 -0
- package/dist/domain/reconstructionCoverage.js +387 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
- package/dist/domain/reconstructionVerificationSchemas.js +8 -0
- package/dist/domain/replayMachine.js +316 -0
- package/dist/domain/replayMachineRuntime.js +215 -0
- package/dist/domain/runtimeCharacterization.js +85 -0
- package/dist/domain/runtimeIdentification.js +210 -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 +50 -29
- package/dist/dotnet/ManagedMemberInspector.js +51 -785
- package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
- package/dist/dotnet/ManagedMemberRows.js +120 -0
- package/dist/dotnet/ManagedMetadataInventory.js +42 -306
- package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
- package/dist/dotnet/ManagedMetadataLayout.js +48 -111
- 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 +102 -350
- package/dist/dotnet/ManagedPeReader.js +59 -28
- package/dist/evaluation/CodexAgentEval.js +132 -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 +61 -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 +4 -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 -146
- 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 +64 -50
- package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
- package/dist/replay/ReplayOutcome.js +95 -0
- package/dist/replay/ReplayProcessLifecycle.js +71 -0
- package/dist/server/ProcessCaptureElicitation.js +157 -0
- package/dist/server/createServer.js +124 -56
- package/dist/server/javascriptApplicationResult.js +85 -0
- 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 +10 -112
- package/dist/server/registerBrowserTools.js +59 -83
- package/dist/server/registerElectronTools.js +48 -49
- package/dist/server/registerEnhancedTools.js +34 -42
- package/dist/server/registerEvidenceResources.js +56 -0
- package/dist/server/registerInvestigationTools/helpers.js +74 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +83 -116
- package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
- package/dist/server/registerManagedTools.js +18 -1
- 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 +10 -274
- package/dist/server/registerOfficialTools.js +73 -59
- package/dist/server/registerSessionRecordTools.js +137 -0
- package/dist/server/registerSessionStatusTool.js +97 -26
- package/dist/server/registerSessionTools.js +60 -164
- package/dist/server/sessionAvailabilityPolicy.js +10 -0
- package/dist/server/toolRegistrationOptions.js +101 -3
- package/dist/server/toolResult.js +15 -4
- package/package.json +11 -11
- package/skills/reverse-engineer-anything/SKILL.md +76 -0
- package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +25 -0
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
- package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
- package/scripts/prepare-node-pty.mjs +0 -35
- package/scripts/rebuild-native.mjs +0 -22
- package/skills/rea-analysis/SKILL.md +0 -222
|
@@ -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 {};
|
|
@@ -6,15 +6,14 @@ import { correlateStaticAndRuntime, staticRuntimeCorrelationInputSchema, } from
|
|
|
6
6
|
import { reconstructionVerificationInputSchema, verifyReconstruction, } from "../domain/reconstructionVerification.js";
|
|
7
7
|
import { changedBehaviorResultSchema, changedBehaviorInputSchema, findChangedBehavior, } from "../domain/changedBehavior.js";
|
|
8
8
|
import { createEvidence } from "../domain/evidence.js";
|
|
9
|
-
import {
|
|
9
|
+
import {} from "../domain/errors.js";
|
|
10
10
|
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
11
|
-
import { err, ok } from "../domain/result.js";
|
|
12
11
|
import { CALL_PATH_PROVIDER, CHANGED_BEHAVIOR_PROVIDER, RECONSTRUCTION_PROVIDER, STATIC_RUNTIME_PROVIDER, } from "./sessionToolPolicies.js";
|
|
13
12
|
import { toCallToolResult } from "./toolResult.js";
|
|
14
|
-
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
|
|
15
13
|
import { mcpProgressReporter } from "./mcpProgress.js";
|
|
16
|
-
import { runDerivedOperation } from "./runDerivedOperation.js";
|
|
14
|
+
import { runDerivedOperation, } from "./runDerivedOperation.js";
|
|
17
15
|
import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "../application/DeferredFileAuthorization.js";
|
|
16
|
+
import { comparisonClosure, evidenceClosure, functionEvidenceIds, investigationContext, isIncomplete, recordWorkflowEvidence, verifyCoverageReadiness, } from "./registerInvestigationTools/helpers.js";
|
|
18
17
|
/** Register Evidence-composed differential investigation workflows. */
|
|
19
18
|
export const registerInvestigationTools = (server, session, contracts, policies) => {
|
|
20
19
|
registerChangedBehavior(server, session, contracts[0], policies);
|
|
@@ -22,14 +21,6 @@ export const registerInvestigationTools = (server, session, contracts, policies)
|
|
|
22
21
|
registerStaticRuntime(server, session, contracts[2]);
|
|
23
22
|
registerReconstruction(server, session, contracts[3]);
|
|
24
23
|
};
|
|
25
|
-
const investigationExecution = (session, signal, inputRoots, integrityContinueEnabled, progress) => ({
|
|
26
|
-
session,
|
|
27
|
-
signal,
|
|
28
|
-
inputRoots,
|
|
29
|
-
integrityContinueEnabled,
|
|
30
|
-
...(progress === undefined ? {} : { progress }),
|
|
31
|
-
});
|
|
32
|
-
const isIncomplete = (status) => status === "unknown" || status === "truncated";
|
|
33
24
|
const registerChangedBehavior = (server, session, contract, policies) => {
|
|
34
25
|
server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
|
|
35
26
|
const parsedInput = safeParseToolInput(changedBehaviorInputSchema, input, contract.name);
|
|
@@ -37,69 +28,16 @@ const registerChangedBehavior = (server, session, contract, policies) => {
|
|
|
37
28
|
return toCallToolResult(parsedInput, contract);
|
|
38
29
|
const parsed = parsedInput.value;
|
|
39
30
|
const investigationRun = parsed.investigation_run;
|
|
40
|
-
if (investigationRun !== undefined)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
writeCapability: "investigation_workspace_write",
|
|
50
|
-
operation: contract.name,
|
|
51
|
-
});
|
|
52
|
-
if (!authorizedWorkspace.ok)
|
|
53
|
-
return toCallToolResult(authorizedWorkspace, contract);
|
|
54
|
-
workspaceAuthorization = authorizedWorkspace.value;
|
|
55
|
-
authorizeInputRead = () => authorizeRootPermission(authority, {
|
|
56
|
-
capability: "investigation_input",
|
|
57
|
-
roots: [investigationRun.left_path, investigationRun.right_path],
|
|
58
|
-
access: "read",
|
|
59
|
-
operation: contract.name,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
const investigated = await runCrossVersionInvestigationValidated(investigationRun, policies.evidenceFiles, {
|
|
63
|
-
...investigationExecution(session, context.mcpReq.signal, policies.inputRoots, policies.integrityContinueEnabled?.() ?? false, progress),
|
|
64
|
-
...(workspaceAuthorization === undefined
|
|
65
|
-
? {}
|
|
66
|
-
: {
|
|
67
|
-
authorizeWorkspaceWrite: workspaceAuthorization.authorizeWrite,
|
|
68
|
-
}),
|
|
69
|
-
...(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,
|
|
70
40
|
});
|
|
71
|
-
if (!investigated.ok)
|
|
72
|
-
return toCallToolResult(investigated, contract);
|
|
73
|
-
const workspace = investigated.value.workspace;
|
|
74
|
-
if (session.retainInvestigationWorkspace(workspace) === "added")
|
|
75
|
-
server.sendResourceListChanged();
|
|
76
|
-
const result = changedBehaviorResultSchema.parse(investigated.value.evidence.normalized_result);
|
|
77
|
-
const toolResult = toCallToolResult(recordWorkflowEvidence(session, investigated.value.evidence, parsed.unknown_registry_approved, isIncomplete(result.behavior_status), {
|
|
78
|
-
question: `Automatic changed behavior run ${result.investigation_run?.run_id ?? "unknown"} remains ${result.behavior_status}`,
|
|
79
|
-
domain: "changed-behavior",
|
|
80
|
-
requiredAuthority: "controlled-replay",
|
|
81
|
-
requiredConfidence: "observed",
|
|
82
|
-
probes: [
|
|
83
|
-
{
|
|
84
|
-
operation: "capture_process_scenario",
|
|
85
|
-
rationale: "Capture both versions under the same bounded scenario and environment.",
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
}), contract);
|
|
89
|
-
return {
|
|
90
|
-
...toolResult,
|
|
91
|
-
content: [
|
|
92
|
-
...toolResult.content,
|
|
93
|
-
{
|
|
94
|
-
type: "resource_link",
|
|
95
|
-
uri: `rea://workspace/${workspace.workspace_id}/revision/${String(workspace.revision)}`,
|
|
96
|
-
name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
|
|
97
|
-
description: "Immutable CAS-linked investigation workspace revision",
|
|
98
|
-
mimeType: "application/json",
|
|
99
|
-
},
|
|
100
|
-
],
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
41
|
const closure = evidenceClosure(session, comparisonClosure(parsed.comparisons));
|
|
104
42
|
if (!closure.ok)
|
|
105
43
|
return toCallToolResult(closure, contract);
|
|
@@ -137,6 +75,74 @@ const registerChangedBehavior = (server, session, contract, policies) => {
|
|
|
137
75
|
return toCallToolResult(recorded, contract);
|
|
138
76
|
});
|
|
139
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
|
+
};
|
|
140
146
|
const registerCallPath = (server, session, contract) => {
|
|
141
147
|
server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
|
|
142
148
|
const parsedInput = safeParseToolInput(callPathInputSchema, input, contract.name);
|
|
@@ -234,6 +240,9 @@ const registerReconstruction = (server, session, contract) => {
|
|
|
234
240
|
if (!parsedInput.ok)
|
|
235
241
|
return toCallToolResult(parsedInput, contract);
|
|
236
242
|
const parsed = parsedInput.value;
|
|
243
|
+
const coverage = verifyCoverageReadiness(session, parsed.coverage);
|
|
244
|
+
if (!coverage.ok)
|
|
245
|
+
return toCallToolResult(coverage, contract);
|
|
237
246
|
const owned = session.exportEvidenceBundle();
|
|
238
247
|
const computed = await runDerivedOperation(context, contract.name, () => verifyReconstruction(parsed.specification, owned, parsed.offset, parsed.limit));
|
|
239
248
|
if (!computed.ok)
|
|
@@ -271,45 +280,3 @@ const registerReconstruction = (server, session, contract) => {
|
|
|
271
280
|
});
|
|
272
281
|
};
|
|
273
282
|
const contractOptions = toolRegistrationOptions;
|
|
274
|
-
const comparisonClosure = (comparisons) => uniqueIds(comparisons.flatMap((evidence) => [
|
|
275
|
-
evidence.evidence_id,
|
|
276
|
-
...evidence.evidence_links,
|
|
277
|
-
]));
|
|
278
|
-
const functionEvidenceIds = (groups) => uniqueIds(groups.flatMap((group) => (Array.isArray(group) ? group : [group]).map(({ evidence_id: id }) => id)));
|
|
279
|
-
const uniqueIds = (ids) => [...new Set(ids)].sort((left, right) => left.localeCompare(right));
|
|
280
|
-
const evidenceClosure = (session, seedIds) => {
|
|
281
|
-
const records = new Map(session
|
|
282
|
-
.exportEvidenceBundle()
|
|
283
|
-
.records.map((evidence) => [evidence.evidence_id, evidence]));
|
|
284
|
-
const visited = new Set();
|
|
285
|
-
const pending = [...seedIds];
|
|
286
|
-
while (pending.length > 0) {
|
|
287
|
-
const evidenceId = pending.pop();
|
|
288
|
-
if (evidenceId === undefined || visited.has(evidenceId))
|
|
289
|
-
continue;
|
|
290
|
-
const evidence = records.get(evidenceId);
|
|
291
|
-
if (evidence === undefined)
|
|
292
|
-
return err(new EvidenceIntegrityError("Investigation input has a dangling Evidence link"));
|
|
293
|
-
visited.add(evidenceId);
|
|
294
|
-
pending.push(...evidence.evidence_links);
|
|
295
|
-
}
|
|
296
|
-
return ok(uniqueIds([...visited]));
|
|
297
|
-
};
|
|
298
|
-
const recordWorkflowEvidence = (...[session, evidence, approved, unresolved, input]) => {
|
|
299
|
-
if (approved !== true || !unresolved) {
|
|
300
|
-
return recordDerivedEvidence(session, evidence, undefined);
|
|
301
|
-
}
|
|
302
|
-
return recordDerivedEvidence(session, evidence, {
|
|
303
|
-
approved: true,
|
|
304
|
-
question: input.question,
|
|
305
|
-
severity: "high",
|
|
306
|
-
domain: input.domain,
|
|
307
|
-
supporting_evidence_ids: [evidence.evidence_id],
|
|
308
|
-
contradicting_evidence_ids: [],
|
|
309
|
-
required_authority: input.requiredAuthority,
|
|
310
|
-
required_confidence: input.requiredConfidence,
|
|
311
|
-
required_environment: null,
|
|
312
|
-
recommended_probes: [...input.probes],
|
|
313
|
-
relationships: [],
|
|
314
|
-
});
|
|
315
|
-
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
|
|
2
|
+
import { javascriptApplicationAnalysisResultSchema } from "../domain/javascriptApplicationAnalysis.js";
|
|
3
|
+
/** Register deterministic pages over one authenticated JavaScript graph. */
|
|
4
|
+
export const registerJavaScriptApplicationGraphResource = (server, session) => {
|
|
5
|
+
server.registerResource("javascript-application-graph-page", new ResourceTemplate("rea://evidence/{evidenceId}/application-graph/{collection}/offset/{offset}/limit/{limit}", {
|
|
6
|
+
list: undefined,
|
|
7
|
+
complete: {
|
|
8
|
+
evidenceId: (prefix) => session
|
|
9
|
+
.exportEvidenceBundle()
|
|
10
|
+
.records.map(({ evidence_id }) => evidence_id)
|
|
11
|
+
.filter((evidenceId) => evidenceId.startsWith(prefix)),
|
|
12
|
+
collection: (prefix) => ["nodes", "edges"].filter((name) => name.startsWith(prefix)),
|
|
13
|
+
},
|
|
14
|
+
}), {
|
|
15
|
+
title: "JavaScript application graph page",
|
|
16
|
+
description: "One deterministic bounded node or edge page from authenticated JavaScript application Evidence.",
|
|
17
|
+
mimeType: "application/json",
|
|
18
|
+
}, (uri, variables) => {
|
|
19
|
+
const evidenceId = stringVariable(variables.evidenceId, uri.href);
|
|
20
|
+
const collection = stringVariable(variables.collection, uri.href);
|
|
21
|
+
if (collection !== "nodes" && collection !== "edges")
|
|
22
|
+
throw new ResourceNotFoundError(uri.href);
|
|
23
|
+
const offset = pageInteger(variables.offset, uri.href, 0, 100_000);
|
|
24
|
+
const limit = pageInteger(variables.limit, uri.href, 1, 500);
|
|
25
|
+
const evidence = session.evidenceById(evidenceId);
|
|
26
|
+
if (evidence === undefined ||
|
|
27
|
+
evidence.operation !== "analyze_javascript_application")
|
|
28
|
+
throw new ResourceNotFoundError(uri.href);
|
|
29
|
+
const analysis = javascriptApplicationAnalysisResultSchema.safeParse(evidence.normalized_result);
|
|
30
|
+
if (!analysis.success)
|
|
31
|
+
throw new ResourceNotFoundError(uri.href);
|
|
32
|
+
const values = analysis.data.graph[collection];
|
|
33
|
+
const items = values.slice(offset, offset + limit);
|
|
34
|
+
const nextOffset = offset + items.length;
|
|
35
|
+
return {
|
|
36
|
+
contents: [
|
|
37
|
+
{
|
|
38
|
+
uri: uri.href,
|
|
39
|
+
mimeType: "application/json",
|
|
40
|
+
text: JSON.stringify({
|
|
41
|
+
evidence_id: evidence.evidence_id,
|
|
42
|
+
graph_id: analysis.data.graph.graph_id,
|
|
43
|
+
collection,
|
|
44
|
+
items,
|
|
45
|
+
offset,
|
|
46
|
+
limit,
|
|
47
|
+
total: values.length,
|
|
48
|
+
next_offset: nextOffset < values.length ? nextOffset : null,
|
|
49
|
+
has_more: nextOffset < values.length,
|
|
50
|
+
}, null, 2),
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const stringVariable = (value, uri) => {
|
|
57
|
+
if (typeof value !== "string")
|
|
58
|
+
throw new ResourceNotFoundError(uri);
|
|
59
|
+
return value;
|
|
60
|
+
};
|
|
61
|
+
const pageInteger = (value, uri, minimum, maximum) => {
|
|
62
|
+
const text = stringVariable(value, uri);
|
|
63
|
+
if (!/^\d+$/u.test(text))
|
|
64
|
+
throw new ResourceNotFoundError(uri);
|
|
65
|
+
const parsed = Number(text);
|
|
66
|
+
if (!Number.isSafeInteger(parsed) || parsed < minimum || parsed > maximum)
|
|
67
|
+
throw new ResourceNotFoundError(uri);
|
|
68
|
+
return parsed;
|
|
69
|
+
};
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { MANAGED_TOOL_CONTRACTS } from "../contracts/managedToolContracts.js";
|
|
2
|
+
import { err } from "../domain/result.js";
|
|
2
3
|
import { registerEvidenceTools } from "./registerEvidenceTools.js";
|
|
3
4
|
/** Register execution-free managed PE/CLI inspection. */
|
|
4
5
|
export const registerManagedTools = (server, analysis, options) => {
|
|
5
|
-
|
|
6
|
+
const targetAwareAnalysis = {
|
|
7
|
+
execute: async (operation, parameters, executionOptions) => {
|
|
8
|
+
const path = operation === "inspect_managed_artifact" &&
|
|
9
|
+
typeof parameters.path === "string"
|
|
10
|
+
? parameters.path
|
|
11
|
+
: undefined;
|
|
12
|
+
if (path !== undefined && options.session !== undefined) {
|
|
13
|
+
const opened = await options.session.open(path, executionOptions?.signal === undefined
|
|
14
|
+
? undefined
|
|
15
|
+
: { signal: executionOptions.signal });
|
|
16
|
+
if (!opened.ok)
|
|
17
|
+
return err(opened.error);
|
|
18
|
+
}
|
|
19
|
+
return analysis.execute(operation, parameters, executionOptions);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
registerEvidenceTools(server, targetAwareAnalysis, MANAGED_TOOL_CONTRACTS, options);
|
|
6
23
|
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { compareManagedMembersEvidenceValidated } from "../../application/ManagedMemberComparisonService.js";
|
|
2
|
+
import { compareManagedMembersReferenceInputSchema } from "../../contracts/managedWorkflowToolContracts.js";
|
|
3
|
+
import { managedMemberComparisonResultSchema } from "../../domain/managedMemberComparison.js";
|
|
4
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
5
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
6
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
7
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
8
|
+
import { managedWorkflowContract } from "./contract.js";
|
|
9
|
+
import { recordManagedSources, resolveManagedEvidence } from "./evidence.js";
|
|
10
|
+
const compareContract = managedWorkflowContract("compare_managed_members");
|
|
11
|
+
/** Register the managed member comparison workflow tool. */
|
|
12
|
+
export const registerCompareManagedMembers = (server, options) => {
|
|
13
|
+
server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
|
|
14
|
+
const parsedInput = safeParseToolInput(compareManagedMembersReferenceInputSchema, input, compareContract.name);
|
|
15
|
+
if (!parsedInput.ok)
|
|
16
|
+
return toCallToolResult(parsedInput, compareContract);
|
|
17
|
+
const resolved = resolveManagedEvidence(options.session, [
|
|
18
|
+
parsedInput.value.left_evidence_id,
|
|
19
|
+
parsedInput.value.right_evidence_id,
|
|
20
|
+
]);
|
|
21
|
+
if (!resolved.ok)
|
|
22
|
+
return toCallToolResult(resolved, compareContract);
|
|
23
|
+
const [left, right] = resolved.value;
|
|
24
|
+
if (left === undefined || right === undefined)
|
|
25
|
+
throw new TypeError("Managed comparison Evidence resolution failed");
|
|
26
|
+
const { left_evidence_id: _leftEvidenceId, right_evidence_id: _rightEvidenceId, ...referencedInput } = parsedInput.value;
|
|
27
|
+
const parsed = { ...referencedInput, left, right };
|
|
28
|
+
const result = await logToolExecution(options.logger, compareContract.name, () => Promise.resolve(compareManagedMembersEvidenceValidated(parsed)));
|
|
29
|
+
if (!result.ok)
|
|
30
|
+
return toCallToolResult(result, compareContract);
|
|
31
|
+
const recorded = recordManagedSources(options.recordEvidence, [
|
|
32
|
+
parsed.left,
|
|
33
|
+
parsed.right,
|
|
34
|
+
]);
|
|
35
|
+
if (!recorded.ok)
|
|
36
|
+
return toCallToolResult(recorded, compareContract);
|
|
37
|
+
const comparison = managedMemberComparisonResultSchema.parse(result.value.normalized_result);
|
|
38
|
+
const unknown = comparison.summary.unknown > 0;
|
|
39
|
+
const output = parsed.unknown_registry_approved === true && unknown
|
|
40
|
+
? options.recordEvidenceWithUnknown?.(result.value, {
|
|
41
|
+
approved: true,
|
|
42
|
+
question: "Which managed members remain unmatched or ambiguous across these versions?",
|
|
43
|
+
severity: "medium",
|
|
44
|
+
domain: "managed-member-comparison",
|
|
45
|
+
supporting_evidence_ids: [result.value.evidence_id],
|
|
46
|
+
contradicting_evidence_ids: [],
|
|
47
|
+
required_authority: "shipped-artifact",
|
|
48
|
+
required_confidence: "observed",
|
|
49
|
+
required_environment: null,
|
|
50
|
+
recommended_probes: [
|
|
51
|
+
{
|
|
52
|
+
operation: "inspect_managed_members",
|
|
53
|
+
rationale: "Repeat static member inspection with complete pages and method bodies.",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
relationships: [],
|
|
57
|
+
})
|
|
58
|
+
: options.recordEvidence?.(result.value);
|
|
59
|
+
if (output !== undefined && !output.ok)
|
|
60
|
+
return toCallToolResult(output, compareContract);
|
|
61
|
+
return toCallToolResult({ ok: true, value: result.value }, compareContract, {
|
|
62
|
+
evidenceResourcesAvailable: output !== undefined,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MANAGED_WORKFLOW_TOOL_CONTRACTS } from "../../contracts/managedWorkflowToolContracts.js";
|
|
2
|
+
/** Locate one managed workflow tool contract by exact name. */
|
|
3
|
+
export const managedWorkflowContract = (name) => {
|
|
4
|
+
const found = MANAGED_WORKFLOW_TOOL_CONTRACTS.find((candidate) => candidate.name === name);
|
|
5
|
+
if (found === undefined)
|
|
6
|
+
throw new Error(`Missing ${name} contract`);
|
|
7
|
+
return found;
|
|
8
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { resolveSessionEvidenceIds } from "../sessionEvidence.js";
|
|
2
|
+
export const resolveManagedEvidence = (session, evidenceIds) => resolveSessionEvidenceIds(session, evidenceIds, {
|
|
3
|
+
operation: "inspect_managed_members",
|
|
4
|
+
predicate: "rea.analysis/v2",
|
|
5
|
+
});
|
|
6
|
+
export const resolveManagedArtifactEvidence = (session, evidenceId) => resolveSessionEvidenceIds(session, [evidenceId], {
|
|
7
|
+
operation: "inspect_managed_artifact",
|
|
8
|
+
predicate: "rea.analysis/v2",
|
|
9
|
+
});
|
|
10
|
+
export const resolveManagedBoundaryEvidence = (session, evidenceId) => resolveSessionEvidenceIds(session, [evidenceId], {
|
|
11
|
+
operation: "inspect_managed_native_boundaries",
|
|
12
|
+
predicate: "rea.analysis/v2",
|
|
13
|
+
});
|
|
14
|
+
export const resolveNativeEvidence = (session, evidenceIds) => {
|
|
15
|
+
const records = [];
|
|
16
|
+
for (const evidenceId of evidenceIds) {
|
|
17
|
+
const operation = session.evidenceById(evidenceId)?.operation;
|
|
18
|
+
const expectedOperation = operation === "inspect_macho" || operation === "analyze_function"
|
|
19
|
+
? operation
|
|
20
|
+
: "inspect_macho or analyze_function";
|
|
21
|
+
const resolved = resolveSessionEvidenceIds(session, [evidenceId], {
|
|
22
|
+
operation: expectedOperation,
|
|
23
|
+
predicate: "rea.analysis/v2",
|
|
24
|
+
});
|
|
25
|
+
if (!resolved.ok)
|
|
26
|
+
return resolved;
|
|
27
|
+
records.push(...resolved.value);
|
|
28
|
+
}
|
|
29
|
+
return { ok: true, value: records };
|
|
30
|
+
};
|
|
31
|
+
export const recordManagedSources = (recordEvidence, sources) => {
|
|
32
|
+
for (const source of sources) {
|
|
33
|
+
const recorded = recordEvidence?.(source);
|
|
34
|
+
if (recorded !== undefined && !recorded.ok)
|
|
35
|
+
return recorded;
|
|
36
|
+
}
|
|
37
|
+
return { ok: true, value: null };
|
|
38
|
+
};
|
|
39
|
+
export const sourceEvidence = (input) => [
|
|
40
|
+
input.managed_artifact,
|
|
41
|
+
input.managed_members,
|
|
42
|
+
input.managed_native_boundaries,
|
|
43
|
+
].filter((evidence) => evidence !== undefined);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { importManagedReconstructionEvidenceValidated } from "../../application/ManagedReconstructionService.js";
|
|
2
|
+
import { managedReconstructionReferenceInputSchema } from "../../contracts/managedWorkflowToolContracts.js";
|
|
3
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
4
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
5
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
6
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
7
|
+
import { managedWorkflowContract } from "./contract.js";
|
|
8
|
+
import { resolveManagedEvidence } from "./evidence.js";
|
|
9
|
+
const reconstructionContract = managedWorkflowContract("import_managed_reconstruction");
|
|
10
|
+
/** Register the managed reconstruction import workflow tool. */
|
|
11
|
+
export const registerImportManagedReconstruction = (server, options) => {
|
|
12
|
+
server.registerTool(reconstructionContract.name, toolRegistrationOptions(reconstructionContract), async (input) => {
|
|
13
|
+
const parsedInput = safeParseToolInput(managedReconstructionReferenceInputSchema, input, reconstructionContract.name);
|
|
14
|
+
if (!parsedInput.ok)
|
|
15
|
+
return toCallToolResult(parsedInput, reconstructionContract);
|
|
16
|
+
const resolved = resolveManagedEvidence(options.session, [
|
|
17
|
+
parsedInput.value.static_members_evidence_id,
|
|
18
|
+
]);
|
|
19
|
+
if (!resolved.ok)
|
|
20
|
+
return toCallToolResult(resolved, reconstructionContract);
|
|
21
|
+
const staticMembers = resolved.value[0];
|
|
22
|
+
if (staticMembers === undefined)
|
|
23
|
+
throw new TypeError("Managed reconstruction Evidence resolution failed");
|
|
24
|
+
const { static_members_evidence_id: _staticMembersEvidenceId, ...referencedInput } = parsedInput.value;
|
|
25
|
+
const parsed = { ...referencedInput, static_members: staticMembers };
|
|
26
|
+
const result = await logToolExecution(options.logger, reconstructionContract.name, () => Promise.resolve(importManagedReconstructionEvidenceValidated(parsed)));
|
|
27
|
+
if (!result.ok)
|
|
28
|
+
return toCallToolResult(result, reconstructionContract);
|
|
29
|
+
const recordedSource = options.recordEvidence?.(parsed.static_members);
|
|
30
|
+
if (recordedSource !== undefined && !recordedSource.ok)
|
|
31
|
+
return toCallToolResult(recordedSource, reconstructionContract);
|
|
32
|
+
const recorded = options.recordEvidence?.(result.value);
|
|
33
|
+
if (recorded !== undefined && !recorded.ok)
|
|
34
|
+
return toCallToolResult(recorded, reconstructionContract);
|
|
35
|
+
return toCallToolResult(result, reconstructionContract, {
|
|
36
|
+
evidenceResourcesAvailable: recorded !== undefined,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { planManagedRuntimeCorrelationEvidenceValidated } from "../../application/ManagedRuntimeCorrelationService.js";
|
|
2
|
+
import { managedRuntimeCorrelationReferenceInputSchema } from "../../contracts/managedWorkflowToolContracts.js";
|
|
3
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
4
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
5
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
6
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
7
|
+
import { managedWorkflowContract } from "./contract.js";
|
|
8
|
+
import { resolveManagedEvidence } from "./evidence.js";
|
|
9
|
+
const runtimeContract = managedWorkflowContract("plan_managed_runtime_correlation");
|
|
10
|
+
/** Register the managed runtime correlation planning workflow tool. */
|
|
11
|
+
export const registerPlanManagedRuntimeCorrelation = (server, options) => {
|
|
12
|
+
server.registerTool(runtimeContract.name, toolRegistrationOptions(runtimeContract), async (input) => {
|
|
13
|
+
const parsedInput = safeParseToolInput(managedRuntimeCorrelationReferenceInputSchema, input, runtimeContract.name);
|
|
14
|
+
if (!parsedInput.ok)
|
|
15
|
+
return toCallToolResult(parsedInput, runtimeContract);
|
|
16
|
+
const resolved = resolveManagedEvidence(options.session, [
|
|
17
|
+
parsedInput.value.static_members_evidence_id,
|
|
18
|
+
]);
|
|
19
|
+
if (!resolved.ok)
|
|
20
|
+
return toCallToolResult(resolved, runtimeContract);
|
|
21
|
+
const staticMembers = resolved.value[0];
|
|
22
|
+
if (staticMembers === undefined)
|
|
23
|
+
throw new TypeError("Managed runtime Evidence resolution failed");
|
|
24
|
+
const { static_members_evidence_id: _staticMembersEvidenceId, ...referencedInput } = parsedInput.value;
|
|
25
|
+
const parsed = { ...referencedInput, static_members: staticMembers };
|
|
26
|
+
const result = await logToolExecution(options.logger, runtimeContract.name, () => Promise.resolve(planManagedRuntimeCorrelationEvidenceValidated(options.runtime, parsed)));
|
|
27
|
+
if (!result.ok)
|
|
28
|
+
return toCallToolResult(result, runtimeContract);
|
|
29
|
+
const recordedSource = options.recordEvidence?.(parsed.static_members);
|
|
30
|
+
if (recordedSource !== undefined && !recordedSource.ok)
|
|
31
|
+
return toCallToolResult(recordedSource, runtimeContract);
|
|
32
|
+
const recorded = options.recordEvidence?.(result.value);
|
|
33
|
+
if (recorded !== undefined && !recorded.ok)
|
|
34
|
+
return toCallToolResult(recorded, runtimeContract);
|
|
35
|
+
return toCallToolResult(result, runtimeContract, {
|
|
36
|
+
evidenceResourcesAvailable: recorded !== undefined,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
};
|