mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
refactor(mcp): consolidate contract and summary policy owners
Resolve application and managed workflow contracts through the canonical name-based resolver, removing catalog-position overloads and the obsolete local facade. Use the existing retained-summary policy for eight offline registrations. Pass only validated delivery detail to that owner while preserving exact typed service inputs and validation, admission, logging, and Evidence recording order. Align export-shape MCP parity coverage with the existing absolute-path contract using an absolute dot alias. Preserve exact caller-path parameters, canonical artifact parity, distinct Evidence identity, and the export comparison assertions.
This commit is contained in:
1 parent
0785223582
commit
3d4f55652b
23 files changed
+126
-208
No files matched your search
@@ -319,45 +319,3 @@ export const APPLICATION_TOOL_CONTRACTS = [
|
||||
],
|
||||
},
|
||||
] as const satisfies readonly ToolContract[];
|
||||
|
||||
/** Resolve one named application contract without relying on array position. */
|
||||
export function applicationToolContract(
|
||||
name: "trace_application_feature",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[0];
|
||||
export function applicationToolContract(
|
||||
name: "trace_javascript_semantics",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[1];
|
||||
export function applicationToolContract(
|
||||
name: "compare_application_versions",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[2];
|
||||
export function applicationToolContract(
|
||||
name: "compare_source_to_bundle",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[3];
|
||||
export function applicationToolContract(
|
||||
name: "compare_javascript_export_shapes",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[4];
|
||||
export function applicationToolContract(
|
||||
name: "build_reconstruction_obligation_ledger",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[5];
|
||||
export function applicationToolContract(
|
||||
name: "evaluate_reconstruction_coverage",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[6];
|
||||
export function applicationToolContract(
|
||||
name: "project_android_application_graph",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[7];
|
||||
export function applicationToolContract(
|
||||
name: "project_apple_application_graph",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[8];
|
||||
export function applicationToolContract(
|
||||
name: "project_harmony_application_graph",
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[9];
|
||||
export function applicationToolContract(
|
||||
name: (typeof APPLICATION_TOOL_CONTRACTS)[number]["name"],
|
||||
): (typeof APPLICATION_TOOL_CONTRACTS)[number] {
|
||||
const contract = APPLICATION_TOOL_CONTRACTS.find(
|
||||
({ name: candidate }) => candidate === name,
|
||||
);
|
||||
if (contract === undefined)
|
||||
throw new Error(`Missing application tool contract: ${name}`);
|
||||
return contract;
|
||||
}
|
||||
@@ -3,13 +3,13 @@ import { runAdmittedToolOperation } from "../admittedToolOperation.js";
|
||||
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
|
||||
import { compareJavaScriptExportShapesEvidence } from "../../application/javascript/JavaScriptApplicationWorkflowService.js";
|
||||
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { recordResult } from "./helpers.js";
|
||||
import type { ApplicationToolRegistration } from "./types.js";
|
||||
|
||||
const contract = applicationToolContract("compare_javascript_export_shapes");
|
||||
const contract = toolContract("compare_javascript_export_shapes");
|
||||
|
||||
/** Register the execution-free exact JavaScript export-shape comparison. */
|
||||
export const registerCompareJavaScriptExportShapesTool = (
|
||||
|
||||
@@ -12,13 +12,13 @@ import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInp
|
||||
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
|
||||
import { compareSourceToBundleEvidence } from "../../application/javascript/JavaScriptApplicationWorkflowService.js";
|
||||
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { recordApplicationResult } from "./helpers.js";
|
||||
import type { ApplicationToolRegistration } from "./types.js";
|
||||
|
||||
const contract = applicationToolContract("compare_source_to_bundle");
|
||||
const contract = toolContract("compare_source_to_bundle");
|
||||
|
||||
/** Register conservative historical-source to bundle comparison. */
|
||||
export const registerCompareSourceToBundleTool = (
|
||||
|
||||
@@ -3,13 +3,13 @@ import { runAdmittedToolOperation } from "../admittedToolOperation.js";
|
||||
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
|
||||
import { compareApplicationVersionsEvidence } from "../../application/javascript/JavaScriptApplicationWorkflowService.js";
|
||||
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { recordResult } from "./helpers.js";
|
||||
import type { ApplicationToolRegistration } from "./types.js";
|
||||
|
||||
const compareContract = applicationToolContract("compare_application_versions");
|
||||
const compareContract = toolContract("compare_application_versions");
|
||||
|
||||
/** Register the provider-neutral JavaScript version comparison tool. */
|
||||
export const registerCompareApplicationVersionsTool = (
|
||||
|
||||
@@ -2,12 +2,12 @@ import type { EvidenceMcpServer } from "../EvidenceMcpServer.js";
|
||||
import { runAdmittedToolOperation } from "../admittedToolOperation.js";
|
||||
|
||||
import { evaluateReconstructionCoverage } from "../../application/ReconstructionCoverageService.js";
|
||||
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { applicationToolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import type { ApplicationToolRegistration } from "./types.js";
|
||||
|
||||
const contract = applicationToolContract("evaluate_reconstruction_coverage");
|
||||
const contract = toolContract("evaluate_reconstruction_coverage");
|
||||
|
||||
/** Register the inline fail-closed reconstruction coverage evaluator. */
|
||||
export const registerCoverageTools = (
|
||||
|
||||
@@ -5,15 +5,13 @@ import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
import { buildResolvedReconstructionObligationLedgerEvidence } from "../../application/ReconstructionObligationLedgerService.js";
|
||||
import { resolveReconstructionObligationLedgerRequest } from "../../application/ReconstructionObligationLedgerRequest.js";
|
||||
import { ok } from "../../domain/result.js";
|
||||
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { recordResult } from "./helpers.js";
|
||||
import type { ApplicationToolRegistration } from "./types.js";
|
||||
|
||||
const contract = applicationToolContract(
|
||||
"build_reconstruction_obligation_ledger",
|
||||
);
|
||||
const contract = toolContract("build_reconstruction_obligation_ledger");
|
||||
|
||||
/** Register conservative reconstruction-obligation generation and closure. */
|
||||
export const registerReconstructionObligationLedgerTool = (
|
||||
|
||||
@@ -5,10 +5,8 @@ import { runAdmittedToolOperation } from "../admittedToolOperation.js";
|
||||
import { projectAndroidApplicationEvidence } from "../../application/android/AndroidApplicationService.js";
|
||||
import { projectAppleApplicationEvidence } from "../../application/apple/AppleApplicationService.js";
|
||||
import { projectHarmonyApplicationEvidence } from "../../application/harmony/HarmonyApplicationService.js";
|
||||
import {
|
||||
APPLICATION_TOOL_CONTRACTS,
|
||||
applicationToolContract,
|
||||
} from "../../contracts/applicationToolContracts.js";
|
||||
import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
|
||||
import type { Result } from "../../domain/result.js";
|
||||
import type { InventoryProjectionEvidenceResult } from "../../application/InventoryProjectionEvidence.js";
|
||||
@@ -26,19 +24,19 @@ export const registerProjectMobileApplicationGraphTools = (
|
||||
registerProjection({
|
||||
server,
|
||||
options,
|
||||
contract: applicationToolContract("project_android_application_graph"),
|
||||
contract: toolContract("project_android_application_graph"),
|
||||
project: projectAndroidApplicationEvidence,
|
||||
});
|
||||
registerProjection({
|
||||
server,
|
||||
options,
|
||||
contract: applicationToolContract("project_apple_application_graph"),
|
||||
contract: toolContract("project_apple_application_graph"),
|
||||
project: projectAppleApplicationEvidence,
|
||||
});
|
||||
registerProjection({
|
||||
server,
|
||||
options,
|
||||
contract: applicationToolContract("project_harmony_application_graph"),
|
||||
contract: toolContract("project_harmony_application_graph"),
|
||||
project: projectHarmonyApplicationEvidence,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,13 +3,13 @@ import { runAdmittedToolOperation } from "../admittedToolOperation.js";
|
||||
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
|
||||
import { traceApplicationFeatureEvidence } from "../../application/javascript/JavaScriptApplicationWorkflowService.js";
|
||||
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { recordResult } from "./helpers.js";
|
||||
import type { ApplicationToolRegistration } from "./types.js";
|
||||
|
||||
const traceContract = applicationToolContract("trace_application_feature");
|
||||
const traceContract = toolContract("trace_application_feature");
|
||||
|
||||
/** Register the provider-neutral JavaScript feature trace tool. */
|
||||
export const registerTraceFeatureTool = (
|
||||
|
||||
@@ -4,13 +4,13 @@ import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInp
|
||||
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
|
||||
import { traceJavaScriptSemanticsEvidenceValidated } from "../../application/javascript/JavaScriptSemanticTraceService.js";
|
||||
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { recordResult } from "./helpers.js";
|
||||
import type { ApplicationToolRegistration } from "./types.js";
|
||||
|
||||
const contract = applicationToolContract("trace_javascript_semantics");
|
||||
const contract = toolContract("trace_javascript_semantics");
|
||||
|
||||
/** Register the bounded JavaScript semantic relation trace tool. */
|
||||
export const registerTraceJavaScriptSemanticsTool = (
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import type { ByteEntropyService } from "../application/binaryDiagnostics/ByteEntropyService.js";
|
||||
import type { EvidenceMcpServer } from "./EvidenceMcpServer.js";
|
||||
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import type { BinaryLayoutService } from "../application/binaryDiagnostics/BinaryLayoutService.js";
|
||||
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
|
||||
import type { EvidenceWriter } from "../application/investigation/InvestigationRecordPort.js";
|
||||
@@ -38,6 +35,10 @@ export const registerBinaryDiagnosticsTools = (
|
||||
withAdmittedAnalysis,
|
||||
);
|
||||
const contract = toolContract("inspect_binary_layout");
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
server.registerTool(
|
||||
contract.name,
|
||||
applicationToolRegistrationOptions(contract),
|
||||
@@ -56,6 +57,7 @@ export const registerBinaryDiagnosticsTools = (
|
||||
contract,
|
||||
);
|
||||
const { detail, ...request } = parsed.data;
|
||||
const parameters = { detail };
|
||||
return runAdmittedToolOperation(
|
||||
server,
|
||||
withAdmittedAnalysis,
|
||||
@@ -66,21 +68,17 @@ export const registerBinaryDiagnosticsTools = (
|
||||
logger,
|
||||
contract.name,
|
||||
async () => {
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(contract.name, {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const inspected = await service.inspect(request, {
|
||||
signal: context.mcpReq.signal,
|
||||
});
|
||||
return detail === "summary" && inspected.ok
|
||||
? summarizeRetainedAnalysis(inspected.value, {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
})
|
||||
return inspected.ok
|
||||
? delivery.projectEvidence(
|
||||
contract.name,
|
||||
parameters,
|
||||
inspected.value,
|
||||
)
|
||||
: inspected;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import type { ByteEntropyService } from "../application/binaryDiagnostics/ByteEntropyService.js";
|
||||
import type { EvidenceMcpServer } from "./EvidenceMcpServer.js";
|
||||
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
|
||||
import type { EvidenceWriter } from "../application/investigation/InvestigationRecordPort.js";
|
||||
import { toolContract } from "../contracts/toolContracts.js";
|
||||
@@ -25,7 +22,10 @@ export const registerByteEntropyTool = (
|
||||
withAdmittedAnalysis: WithAdmittedAnalysis | undefined,
|
||||
): void => {
|
||||
const contract = toolContract("inspect_byte_entropy");
|
||||
const retention = { recordEvidence, evidenceById };
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
server.registerTool(
|
||||
contract.name,
|
||||
toolRegistrationOptions(contract),
|
||||
@@ -40,18 +40,18 @@ export const registerByteEntropyTool = (
|
||||
logger,
|
||||
contract.name,
|
||||
async () => {
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(
|
||||
contract.name,
|
||||
retention,
|
||||
);
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const parameters = { detail };
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const inspected = await entropyService.inspect(request, {
|
||||
signal: context.mcpReq.signal,
|
||||
});
|
||||
return detail === "summary" && inspected.ok
|
||||
? summarizeRetainedAnalysis(inspected.value, retention)
|
||||
return inspected.ok
|
||||
? delivery.projectEvidence(
|
||||
contract.name,
|
||||
parameters,
|
||||
inspected.value,
|
||||
)
|
||||
: inspected;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -7,10 +7,7 @@ import type { WithAdmittedAnalysis } from "./analysisAdmission.js";
|
||||
import { toolContract } from "../contracts/toolContracts.js";
|
||||
import { createEvidenceToolHandler } from "./contractToolHandler.js";
|
||||
import { applicationToolRegistrationOptions } from "./toolRegistrationOptions.js";
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { err } from "../domain/result.js";
|
||||
|
||||
@@ -24,7 +21,10 @@ export const registerDesktopApplicationTool = (
|
||||
evidenceById: EvidenceLookup | undefined,
|
||||
): void => {
|
||||
const contract = toolContract("inspect_desktop_application");
|
||||
const retention = { recordEvidence, evidenceById };
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
const handler = createEvidenceToolHandler(
|
||||
server,
|
||||
async (raw, options) => {
|
||||
@@ -34,13 +34,12 @@ export const registerDesktopApplicationTool = (
|
||||
analysisInputErrorFromIssues(contract.name, parsed.error.issues, raw),
|
||||
);
|
||||
const { detail, ...input } = parsed.data;
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(contract.name, retention);
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const parameters = { detail };
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const result = await service.inspect(input, options);
|
||||
return result.ok && detail === "summary"
|
||||
? summarizeRetainedAnalysis(result.value, retention)
|
||||
return result.ok
|
||||
? delivery.projectEvidence(contract.name, parameters, result.value)
|
||||
: result;
|
||||
},
|
||||
logger,
|
||||
|
||||
@@ -3,10 +3,7 @@ import type { EvidenceMcpServer } from "./EvidenceMcpServer.js";
|
||||
import type { EvmInterfaceService } from "../application/evm/EvmInterfaceService.js";
|
||||
import type { EvidenceWriter } from "../application/investigation/InvestigationRecordPort.js";
|
||||
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { err } from "../domain/result.js";
|
||||
import { evmInterfaceModule } from "../composition/evm.js";
|
||||
@@ -25,6 +22,10 @@ export const registerEvmTools = (
|
||||
evidenceById?: EvidenceLookup,
|
||||
): void => {
|
||||
const contract = evmInterfaceModule.contract;
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
const handler = createEvidenceToolHandler(
|
||||
server,
|
||||
async (rawInput, options) => {
|
||||
@@ -39,14 +40,12 @@ export const registerEvmTools = (
|
||||
),
|
||||
);
|
||||
const { detail, ...input } = parsed.data;
|
||||
const retention = { recordEvidence, evidenceById };
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(contract.name, retention);
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const parameters = { detail };
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const inspected = await service.inspect(input, options);
|
||||
return detail === "summary" && inspected.ok
|
||||
? summarizeRetainedAnalysis(inspected.value, retention)
|
||||
return inspected.ok
|
||||
? delivery.projectEvidence(contract.name, parameters, inspected.value)
|
||||
: inspected;
|
||||
},
|
||||
logger,
|
||||
|
||||
@@ -6,10 +6,10 @@ import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
import { executeManagedMemberComparison } from "../../application/managed/ManagedMemberComparisonService.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { managedWorkflowContract } from "./contract.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import type { ManagedWorkflowToolRegistration } from "./types.js";
|
||||
|
||||
const compareContract = managedWorkflowContract("compare_managed_members");
|
||||
const compareContract = toolContract("compare_managed_members");
|
||||
|
||||
/** Register the managed member comparison workflow tool. */
|
||||
export const registerCompareManagedMembers = (
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import { MANAGED_WORKFLOW_TOOL_CONTRACTS } from "../../contracts/managed/managedWorkflowToolContracts.js";
|
||||
|
||||
/** Locate one managed workflow tool contract by exact name. */
|
||||
export function managedWorkflowContract(
|
||||
name: "compare_managed_members",
|
||||
): (typeof MANAGED_WORKFLOW_TOOL_CONTRACTS)[0];
|
||||
export function managedWorkflowContract(
|
||||
name: "verify_managed_native_boundaries",
|
||||
): (typeof MANAGED_WORKFLOW_TOOL_CONTRACTS)[1];
|
||||
export function managedWorkflowContract(
|
||||
name: "import_managed_reconstruction",
|
||||
): (typeof MANAGED_WORKFLOW_TOOL_CONTRACTS)[2];
|
||||
export function managedWorkflowContract(
|
||||
name: "project_managed_application_graph",
|
||||
): (typeof MANAGED_WORKFLOW_TOOL_CONTRACTS)[3];
|
||||
export function managedWorkflowContract(
|
||||
name: (typeof MANAGED_WORKFLOW_TOOL_CONTRACTS)[number]["name"],
|
||||
) {
|
||||
const found = MANAGED_WORKFLOW_TOOL_CONTRACTS.find(
|
||||
(candidate) => candidate.name === name,
|
||||
);
|
||||
if (found === undefined) throw new Error(`Missing ${name} contract`);
|
||||
return found;
|
||||
}
|
||||
@@ -7,12 +7,10 @@ import {
|
||||
} from "../../application/managed/ManagedReconstructionService.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { managedWorkflowContract } from "./contract.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import type { ManagedWorkflowToolRegistration } from "./types.js";
|
||||
|
||||
const reconstructionContract = managedWorkflowContract(
|
||||
"import_managed_reconstruction",
|
||||
);
|
||||
const reconstructionContract = toolContract("import_managed_reconstruction");
|
||||
|
||||
/** Register the managed reconstruction import workflow tool. */
|
||||
export const registerImportManagedReconstruction = (
|
||||
|
||||
@@ -8,12 +8,10 @@ import type { Evidence } from "../../domain/evidence.js";
|
||||
import { ok } from "../../domain/result.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { managedWorkflowContract } from "./contract.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import type { ManagedWorkflowToolRegistration } from "./types.js";
|
||||
|
||||
const graphContract = managedWorkflowContract(
|
||||
"project_managed_application_graph",
|
||||
);
|
||||
const graphContract = toolContract("project_managed_application_graph");
|
||||
|
||||
/** Register the managed application graph projection workflow tool. */
|
||||
export const registerProjectManagedApplicationGraph = (
|
||||
|
||||
@@ -6,10 +6,10 @@ import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
||||
import { executeManagedNativeBoundaries } from "../../application/managed/ManagedNativeVerificationService.js";
|
||||
import { logToolExecution } from "../toolLogging.js";
|
||||
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
||||
import { managedWorkflowContract } from "./contract.js";
|
||||
import { toolContract } from "../../contracts/toolContracts.js";
|
||||
import type { ManagedWorkflowToolRegistration } from "./types.js";
|
||||
|
||||
const nativeVerificationContract = managedWorkflowContract(
|
||||
const nativeVerificationContract = toolContract(
|
||||
"verify_managed_native_boundaries",
|
||||
);
|
||||
|
||||
|
||||
@@ -7,10 +7,7 @@ import { createEvidenceToolHandler } from "./contractToolHandler.js";
|
||||
import type { WithAdmittedAnalysis } from "./analysisAdmission.js";
|
||||
import { applicationToolRegistrationOptions } from "./toolRegistrationOptions.js";
|
||||
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { err } from "../domain/result.js";
|
||||
|
||||
@@ -24,6 +21,10 @@ export const registerNativeExportsTool = (
|
||||
withAdmittedAnalysis?: WithAdmittedAnalysis,
|
||||
): void => {
|
||||
const contract = toolContract("inspect_native_exports");
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
const handler = createEvidenceToolHandler(
|
||||
server,
|
||||
async (rawInput, options) => {
|
||||
@@ -38,14 +39,12 @@ export const registerNativeExportsTool = (
|
||||
),
|
||||
);
|
||||
const { detail, ...input } = parsed.data;
|
||||
const retention = { recordEvidence, evidenceById };
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(contract.name, retention);
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const parameters = { detail };
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const inspected = await service.inspect(input, options);
|
||||
return detail === "summary" && inspected.ok
|
||||
? summarizeRetainedAnalysis(inspected.value, retention)
|
||||
return inspected.ok
|
||||
? delivery.projectEvidence(contract.name, parameters, inspected.value)
|
||||
: inspected;
|
||||
},
|
||||
logger,
|
||||
|
||||
@@ -13,10 +13,7 @@ import {
|
||||
applicationToolRegistrationOptions,
|
||||
} from "./toolRegistrationOptions.js";
|
||||
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { err } from "../domain/result.js";
|
||||
|
||||
@@ -43,6 +40,10 @@ export const registerPcapTools = (
|
||||
handler(clientContract),
|
||||
);
|
||||
const contract = toolContract("inspect_pcap_capture");
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
const capture = createEvidenceToolHandler(
|
||||
server,
|
||||
async (rawInput, options) => {
|
||||
@@ -57,14 +58,12 @@ export const registerPcapTools = (
|
||||
),
|
||||
);
|
||||
const { detail, ...input } = parsed.data;
|
||||
const retention = { recordEvidence, evidenceById };
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(contract.name, retention);
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const parameters = { detail };
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const result = await service.execute(contract.name, input, options);
|
||||
return detail === "summary" && result.ok
|
||||
? summarizeRetainedAnalysis(result.value, retention)
|
||||
return result.ok
|
||||
? delivery.projectEvidence(contract.name, parameters, result.value)
|
||||
: result;
|
||||
},
|
||||
logger,
|
||||
|
||||
@@ -7,10 +7,7 @@ import type { EvidenceMcpServer } from "./EvidenceMcpServer.js";
|
||||
import type { WasmArtifactService } from "../application/wasm/WasmArtifactService.js";
|
||||
import type { EvidenceWriter } from "../application/investigation/InvestigationRecordPort.js";
|
||||
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { err } from "../domain/result.js";
|
||||
import { wasmArtifactModule } from "../composition/wasm.js";
|
||||
@@ -64,6 +61,10 @@ export const registerWasmTools = (
|
||||
compareHandler(comparison),
|
||||
);
|
||||
const contract = wasmArtifactModule.contract;
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
const handler = createEvidenceToolHandler(
|
||||
server,
|
||||
async (rawInput, options) => {
|
||||
@@ -78,14 +79,12 @@ export const registerWasmTools = (
|
||||
),
|
||||
);
|
||||
const { detail, ...input } = parsed.data;
|
||||
const retention = { recordEvidence, evidenceById };
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(contract.name, retention);
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const parameters = { detail };
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const inspected = await service.inspect(input, options);
|
||||
return detail === "summary" && inspected.ok
|
||||
? summarizeRetainedAnalysis(inspected.value, retention)
|
||||
return inspected.ok
|
||||
? delivery.projectEvidence(contract.name, parameters, inspected.value)
|
||||
: inspected;
|
||||
},
|
||||
logger,
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import type { EvidenceMcpServer } from "./EvidenceMcpServer.js";
|
||||
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
|
||||
import {
|
||||
requireAnalysisViewRetention,
|
||||
summarizeRetainedAnalysis,
|
||||
} from "../application/analysisView/AnalysisViewService.js";
|
||||
import { retainedSummaryDelivery } from "./retainedSummaryDelivery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { redactExplicitFailure } from "../domain/explicitSensitiveFailure.js";
|
||||
import { captureSensitiveValues } from "../domain/webNetworkCapture.js";
|
||||
@@ -26,6 +23,10 @@ export const registerWebNetworkCaptureTool = (
|
||||
evidenceById?: EvidenceLookup,
|
||||
): void => {
|
||||
const contract = toolContract("inspect_web_network_capture");
|
||||
const delivery = retainedSummaryDelivery(new Set([contract.name]), {
|
||||
recordEvidence,
|
||||
evidenceById,
|
||||
});
|
||||
const registration = applicationToolRegistrationOptions(contract);
|
||||
// Keep the exact advertised contract; the shared service validates raw input
|
||||
// before effects so caller-declared sensitivity also covers invalid arguments.
|
||||
@@ -47,14 +48,12 @@ export const registerWebNetworkCaptureTool = (
|
||||
),
|
||||
);
|
||||
const { detail, ...input } = parsed.data;
|
||||
const retention = { recordEvidence, evidenceById };
|
||||
if (detail === "summary") {
|
||||
const ready = requireAnalysisViewRetention(contract.name, retention);
|
||||
if (!ready.ok) return ready;
|
||||
}
|
||||
const parameters = { detail };
|
||||
const ready = delivery.preflight(contract.name, parameters);
|
||||
if (!ready.ok) return ready;
|
||||
const inspected = await service.inspect(input, options);
|
||||
return detail === "summary" && inspected.ok
|
||||
? summarizeRetainedAnalysis(inspected.value, retention)
|
||||
return inspected.ok
|
||||
? delivery.projectEvidence(contract.name, parameters, inspected.value)
|
||||
: inspected;
|
||||
},
|
||||
logger,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it, onTestFinished } from "vitest";
|
||||
import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
|
||||
import { join, relative, resolve } from "node:path";
|
||||
import { join, resolve, sep } from "node:path";
|
||||
import { Ajv2020 } from "ajv/dist/2020.js";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -166,22 +166,22 @@ describe("application workflow MCP parity", () => {
|
||||
right_export_name: "default",
|
||||
};
|
||||
try {
|
||||
const relativePath = relative(process.cwd(), leftRoot);
|
||||
const relativeApplication = await client.callTool({
|
||||
const selectedPath = `${leftRoot}${sep}.`;
|
||||
const selectedApplication = await client.callTool({
|
||||
name: "analyze_javascript_application",
|
||||
arguments: { input_path: relativePath },
|
||||
arguments: { input_path: selectedPath },
|
||||
});
|
||||
expect(relativeApplication.isError).not.toBe(true);
|
||||
const relativeEvidence = parseEvidence(
|
||||
relativeApplication.structuredContent,
|
||||
expect(selectedApplication.isError).not.toBe(true);
|
||||
const selectedEvidence = parseEvidence(
|
||||
selectedApplication.structuredContent,
|
||||
);
|
||||
expect(relativeEvidence.parameters.input_path).toBe(relativePath);
|
||||
expect(selectedEvidence.parameters.input_path).toBe(selectedPath);
|
||||
expect(left.value.parameters.input_path).toBe(leftRoot);
|
||||
expect(relativeEvidence.normalized_result).toEqual(
|
||||
expect(selectedEvidence.normalized_result).toEqual(
|
||||
left.value.normalized_result,
|
||||
);
|
||||
expect(relativeEvidence.subject).toEqual(left.value.subject);
|
||||
expect(relativeEvidence.evidence_id).not.toBe(left.value.evidence_id);
|
||||
expect(selectedEvidence.subject).toEqual(left.value.subject);
|
||||
expect(selectedEvidence.evidence_id).not.toBe(left.value.evidence_id);
|
||||
const full = await client.callTool({
|
||||
name: "compare_javascript_export_shapes",
|
||||
arguments: { left: left.value, right: right.value, ...selectors },
|
||||
|
||||
Reference in new issue
Block a user