rea-agents 2.0.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.
Files changed (246) hide show
  1. package/README.md +78 -32
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +24 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +1 -23
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +156 -238
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  26. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  27. package/dist/application/EnhancedToolPagination.js +22 -0
  28. package/dist/application/EnhancedToolTypes.js +4 -0
  29. package/dist/application/EnhancedTools.js +20 -37
  30. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  31. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  32. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  33. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  34. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  35. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  36. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  37. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  38. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  39. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  40. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  41. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  42. package/dist/application/JavaScriptJsonModules.js +39 -0
  43. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  44. package/dist/application/JavaScriptReplayPermission.js +16 -0
  45. package/dist/application/JavaScriptReplayService.js +182 -156
  46. package/dist/application/LinuxHopper.js +10 -0
  47. package/dist/application/MacHopper.js +22 -11
  48. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  49. package/dist/application/PermissionAuthority.js +106 -63
  50. package/dist/application/ProcessCaptureCapability.js +1 -1
  51. package/dist/application/ProcessCapturePermission.js +13 -0
  52. package/dist/application/ProcessCli.js +2 -12
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProjectPermissionStore.js +48 -9
  55. package/dist/application/RealHopperAssertions.js +76 -0
  56. package/dist/application/ReconstructionCoverageService.js +69 -0
  57. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  58. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  59. package/dist/application/Setup.js +147 -259
  60. package/dist/application/SetupClientConfiguration.js +220 -0
  61. package/dist/application/SetupClients.js +24 -2
  62. package/dist/application/SetupPlan.js +123 -12
  63. package/dist/application/SetupSkill.js +26 -12
  64. package/dist/application/SupportedClients.js +1 -0
  65. package/dist/application/Uninstall.js +6 -3
  66. package/dist/application/WindowsCapabilities.js +86 -0
  67. package/dist/artifacts/AsarArtifactReader.js +11 -0
  68. package/dist/browser/BrowserProcessStartup.js +88 -0
  69. package/dist/browser/CdpCaptureDocuments.js +12 -8
  70. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  71. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  72. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  73. package/dist/browser/CdpCaptureEventState.js +1 -0
  74. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  75. package/dist/browser/CdpCaptureEvents.js +29 -496
  76. package/dist/browser/CdpObservationSession.js +51 -8
  77. package/dist/browser/CdpPageCapture.js +12 -133
  78. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  79. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  80. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  81. package/dist/browser/PngVisualDiff.js +9 -2
  82. package/dist/catalogIdentity.js +4 -0
  83. package/dist/cli/artifactCommands.js +82 -0
  84. package/dist/cli/coreAnalysisCommands.js +232 -0
  85. package/dist/cli/managedCommands.js +397 -0
  86. package/dist/cli/managedProjectGraphCommand.js +24 -0
  87. package/dist/cli/options.js +9 -0
  88. package/dist/cli/setupCommands.js +108 -0
  89. package/dist/cli/types.js +1 -0
  90. package/dist/cli/utilityCommands.js +122 -0
  91. package/dist/cli.js +10 -768
  92. package/dist/cliApplicationCommands.js +118 -4
  93. package/dist/cliBrowserAdvancedCommands.js +73 -16
  94. package/dist/cliBrowserCommands.js +39 -115
  95. package/dist/cliCommandNames.js +4 -0
  96. package/dist/cliElectronCommands.js +33 -62
  97. package/dist/cliEvidenceCommands.js +13 -2
  98. package/dist/cliInvestigationCommands.js +53 -10
  99. package/dist/cliObservationOptions.js +137 -0
  100. package/dist/cliPolicyCommands.js +80 -46
  101. package/dist/cliSetup.js +289 -0
  102. package/dist/config/environment.js +107 -0
  103. package/dist/config/parseConfig.js +228 -0
  104. package/dist/config/parsers.js +68 -0
  105. package/dist/config/permissions.js +30 -0
  106. package/dist/config/types.js +1 -0
  107. package/dist/config.js +1 -375
  108. package/dist/contracts/applicationToolContracts.js +134 -0
  109. package/dist/contracts/managedToolContracts.js +1 -1
  110. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  111. package/dist/contracts/providerSelection.js +2 -0
  112. package/dist/contracts/toolContracts.js +2 -2
  113. package/dist/contracts/toolEffects.js +14 -0
  114. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  115. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  116. package/dist/contracts/toolOutputSchemas.js +2 -550
  117. package/dist/domain/analysisErrorPresentation.js +234 -0
  118. package/dist/domain/analysisErrorProjection.js +284 -0
  119. package/dist/domain/artifactComparison.js +34 -15
  120. package/dist/domain/binaryTarget.js +87 -37
  121. package/dist/domain/browserObservation.js +1 -285
  122. package/dist/domain/browserObservationSchemas.js +286 -0
  123. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  124. package/dist/domain/errors.js +4 -486
  125. package/dist/domain/functionComparison.js +4 -165
  126. package/dist/domain/functionComparisonDimensions.js +164 -0
  127. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  128. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  129. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  130. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  131. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  132. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  133. package/dist/domain/javascriptSemanticIr.js +30 -0
  134. package/dist/domain/javascriptSemanticProjection.js +366 -0
  135. package/dist/domain/javascriptSemanticState.js +40 -0
  136. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  137. package/dist/domain/javascriptSemanticValues.js +352 -0
  138. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  139. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  140. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  141. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  142. package/dist/domain/knownPageCoverage.js +21 -0
  143. package/dist/domain/managedApplicationGraph.js +14 -364
  144. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  145. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  146. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  147. package/dist/domain/managedArtifact.js +16 -8
  148. package/dist/domain/managedMemberComparison.js +37 -391
  149. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  150. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  151. package/dist/domain/managedNativeVerification.js +27 -389
  152. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  153. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  154. package/dist/domain/managedReconstruction.js +82 -69
  155. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  156. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  157. package/dist/domain/permissionPolicy.js +2 -0
  158. package/dist/domain/reconstructionCoverage.js +387 -0
  159. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  160. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  161. package/dist/domain/runtimeCharacterization.js +85 -0
  162. package/dist/domain/webBundleAnalyzer.js +3 -409
  163. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  164. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  165. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  166. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  167. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  168. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  169. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  170. package/dist/dotnet/ManagedMemberRows.js +120 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  172. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  173. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  174. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  175. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  176. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  177. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  178. package/dist/dotnet/ManagedPeReader.js +59 -28
  179. package/dist/generatedPackageMetadata.js +2 -2
  180. package/dist/ghidra/GhidraClient.js +76 -91
  181. package/dist/ghidra/GhidraClientStartup.js +29 -0
  182. package/dist/ghidra/GhidraClientWire.js +34 -0
  183. package/dist/ghidra/GhidraDefaults.js +1 -1
  184. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  185. package/dist/ghidra/GhidraInstallation.js +20 -15
  186. package/dist/ghidra/GhidraLauncher.js +93 -29
  187. package/dist/ghidra/GhidraProvider.js +61 -161
  188. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  189. package/dist/ghidra/GhidraSessionValues.js +2 -0
  190. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  191. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  192. package/dist/ghidra/GhidraTransport.js +71 -0
  193. package/dist/identity.js +3 -2
  194. package/dist/main/messages.js +5 -0
  195. package/dist/main/reload.js +49 -0
  196. package/dist/main/shutdown.js +25 -0
  197. package/dist/main/startup.js +14 -0
  198. package/dist/main/state.js +26 -0
  199. package/dist/main/transport.js +61 -0
  200. package/dist/main/types.js +1 -0
  201. package/dist/main.js +35 -146
  202. package/dist/process/PrivateRuntimeRoot.js +3 -2
  203. package/dist/process/ProcessOwnership.js +35 -0
  204. package/dist/process/ProviderProcess.js +2 -0
  205. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  206. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  207. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  208. package/dist/replay/ReplayOutcome.js +95 -0
  209. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  210. package/dist/server/ProcessCaptureElicitation.js +157 -0
  211. package/dist/server/createServer.js +119 -54
  212. package/dist/server/registerApplicationTools/characterization.js +57 -0
  213. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  214. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  215. package/dist/server/registerApplicationTools/coverage.js +84 -0
  216. package/dist/server/registerApplicationTools/helpers.js +42 -0
  217. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  218. package/dist/server/registerApplicationTools/types.js +1 -0
  219. package/dist/server/registerApplicationTools.js +10 -112
  220. package/dist/server/registerBrowserTools.js +59 -83
  221. package/dist/server/registerElectronTools.js +31 -46
  222. package/dist/server/registerEnhancedTools.js +34 -42
  223. package/dist/server/registerEvidenceResources.js +54 -0
  224. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  225. package/dist/server/registerInvestigationTools/types.js +1 -0
  226. package/dist/server/registerInvestigationTools.js +83 -116
  227. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  228. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  229. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  230. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  231. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  232. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  233. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  234. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  235. package/dist/server/registerManagedWorkflowTools.js +10 -274
  236. package/dist/server/registerOfficialTools.js +73 -59
  237. package/dist/server/registerSessionRecordTools.js +137 -0
  238. package/dist/server/registerSessionStatusTool.js +2 -1
  239. package/dist/server/registerSessionTools.js +60 -164
  240. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  241. package/dist/server/toolRegistrationOptions.js +101 -3
  242. package/dist/server/toolResult.js +5 -0
  243. package/package.json +10 -11
  244. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +20 -7
  245. package/scripts/prepare-node-pty.mjs +0 -35
  246. package/scripts/rebuild-native.mjs +0 -22
package/dist/config.js CHANGED
@@ -1,375 +1 @@
1
- import { z } from "zod";
2
- import { isAbsolute } from "node:path";
3
- import { ConfigurationError } from "./domain/errors.js";
4
- import { err, ok } from "./domain/result.js";
5
- import { browserEndpointSchema, browserOriginSchema, isLiteralLoopbackHostname, } from "./domain/browserObservation.js";
6
- import { electronFileRootsSchema } from "./domain/electronObservation.js";
7
- import { analysisProviderSelectorSchema, } from "./contracts/providerSelection.js";
8
- const DEFAULT_HOPPER_LAUNCHER_PATH = "/Applications/Hopper Disassembler.app/Contents/MacOS/hopper";
9
- const defaultHopperLauncherPath = () => process.platform === "linux"
10
- ? "/opt/hopper/bin/Hopper"
11
- : DEFAULT_HOPPER_LAUNCHER_PATH;
12
- const environmentSchema = z
13
- .object({
14
- REA_ANALYSIS_PROVIDER: analysisProviderSelectorSchema.default("auto"),
15
- GHIDRA_INSTALL_DIR: z
16
- .string()
17
- .min(1)
18
- .refine(isAbsolute, "GHIDRA_INSTALL_DIR must be absolute")
19
- .optional(),
20
- JAVA_HOME: z
21
- .string()
22
- .min(1)
23
- .refine(isAbsolute, "JAVA_HOME must be absolute")
24
- .optional(),
25
- HOPPER_LAUNCHER_PATH: z.string().min(1).optional(),
26
- HOPPER_TARGET_PATH: z.string().min(1).optional(),
27
- HOPPER_TARGET_KIND: z
28
- .enum(["executable", "database"])
29
- .default("executable"),
30
- HOPPER_LOADER_ARGS_JSON: z.string().optional(),
31
- REA_LOG_LEVEL: z
32
- .enum(["trace", "debug", "info", "warn", "error", "fatal", "silent"])
33
- .default("info"),
34
- REA_PROCESS_CAPTURE_ENABLED: z.enum(["true", "false"]).default("false"),
35
- REA_ARTIFACT_NATIVE_MOUNT_ENABLED: z
36
- .enum(["true", "false"])
37
- .default("false"),
38
- REA_ARTIFACT_INTEGRITY_CONTINUE_ENABLED: z
39
- .enum(["true", "false"])
40
- .default("false"),
41
- REA_PROCESS_ALLOW_EXTERNAL_NETWORK: z
42
- .enum(["true", "false"])
43
- .default("false"),
44
- REA_PROCESS_EXECUTABLE_ROOTS_JSON: z.string().default("[]"),
45
- REA_PROCESS_WORKING_ROOTS_JSON: z.string().default("[]"),
46
- REA_PROCESS_ALLOWED_ENV_JSON: z.string().default("[]"),
47
- REA_EVIDENCE_ROOTS_JSON: z.string().default("[]"),
48
- REA_INVESTIGATION_INPUT_ROOTS_JSON: z.string().default("[]"),
49
- REA_ANALYSIS_SNAPSHOT_ROOTS_JSON: z.string().default("[]"),
50
- REA_REFERENCE_ROOTS_JSON: z.string().default("[]"),
51
- REA_REFERENCE_SECRET_PATTERNS_JSON: z.string().default("[]"),
52
- REA_BROWSER_OBSERVE_ENABLED: z.enum(["true", "false"]).default("false"),
53
- REA_BROWSER_CDP_ENDPOINTS_JSON: z.string().default("[]"),
54
- REA_BROWSER_ALLOWED_ORIGINS_JSON: z.string().default("[]"),
55
- REA_ELECTRON_OBSERVE_ENABLED: z.enum(["true", "false"]).default("false"),
56
- REA_ELECTRON_CDP_ENDPOINTS_JSON: z.string().default("[]"),
57
- REA_ELECTRON_FILE_ROOTS_JSON: z.string().default("[]"),
58
- REA_JAVASCRIPT_REPLAY_ENABLED: z.enum(["true", "false"]).default("false"),
59
- REA_JAVASCRIPT_REPLAY_ROOTS_JSON: z.string().default("[]"),
60
- REA_JAVASCRIPT_REPLAY_NODE_PATH: z
61
- .string()
62
- .min(1)
63
- .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_NODE_PATH must be absolute")
64
- .default(process.execPath),
65
- REA_JAVASCRIPT_REPLAY_BWRAP_PATH: z
66
- .string()
67
- .min(1)
68
- .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_BWRAP_PATH must be absolute")
69
- .default("/usr/bin/bwrap"),
70
- REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH: z
71
- .string()
72
- .min(1)
73
- .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH must be absolute")
74
- .default("/usr/bin/systemd-run"),
75
- REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH: z
76
- .string()
77
- .min(1)
78
- .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH must be absolute")
79
- .default("/usr/bin/systemctl"),
80
- REA_JAVASCRIPT_REPLAY_SHELL_PATH: z
81
- .string()
82
- .min(1)
83
- .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SHELL_PATH must be absolute")
84
- .default("/usr/bin/bash"),
85
- REA_MANAGED_RUNTIME_ENABLED: z.enum(["true", "false"]).default("false"),
86
- REA_MANAGED_RUNTIME_ROOTS_JSON: z.string().default("[]"),
87
- REA_MANAGED_RUNTIME_EXECUTABLE_PATH: z
88
- .string()
89
- .min(1)
90
- .refine(isAbsolute, "REA_MANAGED_RUNTIME_EXECUTABLE_PATH must be absolute")
91
- .default("/usr/bin/dotnet"),
92
- REA_PERMISSION_PROJECT_ROOT: z.string().min(1).optional(),
93
- REA_PERMISSION_PROJECT_STORE: z.string().min(1).optional(),
94
- })
95
- .refine((value) => (value.REA_PERMISSION_PROJECT_ROOT === undefined) ===
96
- (value.REA_PERMISSION_PROJECT_STORE === undefined), {
97
- message: "REA_PERMISSION_PROJECT_ROOT and REA_PERMISSION_PROJECT_STORE must be configured together",
98
- });
99
- const parseStringArray = (encoded, name) => {
100
- try {
101
- const parsed = z
102
- .array(z.string().min(1))
103
- .max(128)
104
- .safeParse(JSON.parse(encoded));
105
- return parsed.success
106
- ? ok(parsed.data)
107
- : err(new ConfigurationError(parsed.error.issues.some(({ code }) => code === "too_big")
108
- ? `${name} must encode at most 128 strings`
109
- : `${name} must encode an array of strings`, { cause: parsed.error }));
110
- }
111
- catch (cause) {
112
- return err(new ConfigurationError(`${name} must be valid JSON`, { cause }));
113
- }
114
- };
115
- const parseBrowserArray = (encoded, name, itemSchema, maximum) => {
116
- try {
117
- const parsed = z
118
- .array(itemSchema)
119
- .max(maximum)
120
- .safeParse(JSON.parse(encoded));
121
- return parsed.success
122
- ? ok([...new Set(parsed.data)].sort())
123
- : err(new ConfigurationError(`${name} must encode valid browser scopes`, {
124
- cause: parsed.error,
125
- }));
126
- }
127
- catch (cause) {
128
- return err(new ConfigurationError(`${name} must be valid JSON`, { cause }));
129
- }
130
- };
131
- const parseElectronFileRoots = (encoded) => {
132
- try {
133
- const decoded = JSON.parse(encoded);
134
- if (Array.isArray(decoded) && decoded.length === 0)
135
- return ok([]);
136
- const parsed = electronFileRootsSchema.safeParse(decoded);
137
- return parsed.success
138
- ? ok(parsed.data)
139
- : err(new ConfigurationError("REA_ELECTRON_FILE_ROOTS_JSON must encode absolute roots", { cause: parsed.error }));
140
- }
141
- catch (cause) {
142
- return err(new ConfigurationError("REA_ELECTRON_FILE_ROOTS_JSON must be valid JSON", { cause }));
143
- }
144
- };
145
- const filePolicy = (roots) => ({
146
- roots,
147
- maxBytes: 64 * 1024 * 1024,
148
- maxDepth: 64,
149
- maxStringLength: 1024 * 1024,
150
- maxNodes: 1_000_000,
151
- });
152
- const permissionScope = (capability, roots, options = {}) => ({
153
- capability,
154
- roots,
155
- executables: options.executables ?? [],
156
- environment_names: options.environment_names ?? [],
157
- ...(options.origins === undefined ? {} : { origins: options.origins }),
158
- network: options.network ?? "none",
159
- mount: options.mount ?? false,
160
- });
161
- const administratorGrants = (ceilings) => ceilings.map((ceiling) => ({
162
- ...ceiling,
163
- grant_id: `administrator:${ceiling.capability}`,
164
- lifetime: "administrator",
165
- operation_identity: null,
166
- expires_at: null,
167
- }));
168
- const parseLoaderArgs = (encoded) => {
169
- if (encoded === undefined)
170
- return ok([]);
171
- let decoded;
172
- try {
173
- decoded = JSON.parse(encoded);
174
- }
175
- catch (cause) {
176
- return err(new ConfigurationError("HOPPER_LOADER_ARGS_JSON must be valid JSON", {
177
- cause,
178
- }));
179
- }
180
- const parsed = z.array(z.string()).safeParse(decoded);
181
- return parsed.success
182
- ? ok(parsed.data)
183
- : err(new ConfigurationError("HOPPER_LOADER_ARGS_JSON must encode an array of strings", { cause: parsed.error }));
184
- };
185
- /**
186
- * Parse provider and authority configuration once at the composition root.
187
- * Explicit loader arguments override REA's header-derived defaults for a
188
- * supported target, allowing callers to refine Hopper's loader behavior without
189
- * bypassing REA's path and executable-header checks.
190
- */
191
- export const parseConfig = (environment) => {
192
- const parsedEnvironment = environmentSchema.safeParse(environment);
193
- if (!parsedEnvironment.success) {
194
- return err(new ConfigurationError("Invalid REA environment configuration", {
195
- cause: parsedEnvironment.error,
196
- }));
197
- }
198
- const loaderArgs = parseLoaderArgs(parsedEnvironment.data.HOPPER_LOADER_ARGS_JSON);
199
- if (!loaderArgs.ok)
200
- return loaderArgs;
201
- const executableRoots = parseStringArray(parsedEnvironment.data.REA_PROCESS_EXECUTABLE_ROOTS_JSON, "REA_PROCESS_EXECUTABLE_ROOTS_JSON");
202
- if (!executableRoots.ok)
203
- return executableRoots;
204
- const workingRoots = parseStringArray(parsedEnvironment.data.REA_PROCESS_WORKING_ROOTS_JSON, "REA_PROCESS_WORKING_ROOTS_JSON");
205
- if (!workingRoots.ok)
206
- return workingRoots;
207
- const allowedEnvironment = parseStringArray(parsedEnvironment.data.REA_PROCESS_ALLOWED_ENV_JSON, "REA_PROCESS_ALLOWED_ENV_JSON");
208
- if (!allowedEnvironment.ok)
209
- return allowedEnvironment;
210
- const evidenceRoots = parseStringArray(parsedEnvironment.data.REA_EVIDENCE_ROOTS_JSON, "REA_EVIDENCE_ROOTS_JSON");
211
- if (!evidenceRoots.ok)
212
- return evidenceRoots;
213
- const investigationInputRoots = parseStringArray(parsedEnvironment.data.REA_INVESTIGATION_INPUT_ROOTS_JSON, "REA_INVESTIGATION_INPUT_ROOTS_JSON");
214
- if (!investigationInputRoots.ok)
215
- return investigationInputRoots;
216
- const analysisSnapshotRoots = parseStringArray(parsedEnvironment.data.REA_ANALYSIS_SNAPSHOT_ROOTS_JSON, "REA_ANALYSIS_SNAPSHOT_ROOTS_JSON");
217
- if (!analysisSnapshotRoots.ok)
218
- return analysisSnapshotRoots;
219
- const referenceRoots = parseStringArray(parsedEnvironment.data.REA_REFERENCE_ROOTS_JSON, "REA_REFERENCE_ROOTS_JSON");
220
- if (!referenceRoots.ok)
221
- return referenceRoots;
222
- const secretPatterns = parseStringArray(parsedEnvironment.data.REA_REFERENCE_SECRET_PATTERNS_JSON, "REA_REFERENCE_SECRET_PATTERNS_JSON");
223
- if (!secretPatterns.ok)
224
- return secretPatterns;
225
- const browserEndpoints = parseBrowserArray(parsedEnvironment.data.REA_BROWSER_CDP_ENDPOINTS_JSON, "REA_BROWSER_CDP_ENDPOINTS_JSON", browserEndpointSchema, 16);
226
- if (!browserEndpoints.ok)
227
- return browserEndpoints;
228
- const browserOrigins = parseBrowserArray(parsedEnvironment.data.REA_BROWSER_ALLOWED_ORIGINS_JSON, "REA_BROWSER_ALLOWED_ORIGINS_JSON", browserOriginSchema, 32);
229
- if (!browserOrigins.ok)
230
- return browserOrigins;
231
- const electronEndpoints = parseBrowserArray(parsedEnvironment.data.REA_ELECTRON_CDP_ENDPOINTS_JSON, "REA_ELECTRON_CDP_ENDPOINTS_JSON", browserEndpointSchema, 16);
232
- if (!electronEndpoints.ok)
233
- return electronEndpoints;
234
- const electronFileRoots = parseElectronFileRoots(parsedEnvironment.data.REA_ELECTRON_FILE_ROOTS_JSON);
235
- if (!electronFileRoots.ok)
236
- return electronFileRoots;
237
- const javascriptReplayRoots = parseStringArray(parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_ROOTS_JSON, "REA_JAVASCRIPT_REPLAY_ROOTS_JSON");
238
- if (!javascriptReplayRoots.ok)
239
- return javascriptReplayRoots;
240
- if (javascriptReplayRoots.value.some((root) => !isAbsolute(root)))
241
- return err(new ConfigurationError("REA_JAVASCRIPT_REPLAY_ROOTS_JSON must encode absolute roots"));
242
- const managedRuntimeRoots = parseStringArray(parsedEnvironment.data.REA_MANAGED_RUNTIME_ROOTS_JSON, "REA_MANAGED_RUNTIME_ROOTS_JSON");
243
- if (!managedRuntimeRoots.ok)
244
- return managedRuntimeRoots;
245
- if (managedRuntimeRoots.value.some((root) => !isAbsolute(root)))
246
- return err(new ConfigurationError("REA_MANAGED_RUNTIME_ROOTS_JSON must encode absolute roots"));
247
- const permissionCeilings = [
248
- ...(parsedEnvironment.data.REA_PROCESS_CAPTURE_ENABLED === "true"
249
- ? [
250
- permissionScope("process_capture", workingRoots.value, {
251
- executables: executableRoots.value,
252
- environment_names: allowedEnvironment.value,
253
- network: parsedEnvironment.data.REA_PROCESS_ALLOW_EXTERNAL_NETWORK ===
254
- "true"
255
- ? "external"
256
- : "none",
257
- }),
258
- ]
259
- : []),
260
- permissionScope("evidence_read", evidenceRoots.value),
261
- permissionScope("evidence_write", evidenceRoots.value),
262
- permissionScope("investigation_input", investigationInputRoots.value),
263
- permissionScope("investigation_workspace_read", evidenceRoots.value),
264
- permissionScope("investigation_workspace_write", evidenceRoots.value),
265
- permissionScope("snapshot_read", analysisSnapshotRoots.value),
266
- permissionScope("snapshot_write", analysisSnapshotRoots.value),
267
- permissionScope("artifact_extract", ["/"]),
268
- permissionScope("reference_read", referenceRoots.value),
269
- ...(parsedEnvironment.data.REA_BROWSER_OBSERVE_ENABLED === "true"
270
- ? [
271
- permissionScope("browser_observe", [], {
272
- origins: [...browserEndpoints.value, ...browserOrigins.value],
273
- network: browserNetworkScope(browserOrigins.value),
274
- }),
275
- ]
276
- : []),
277
- ...(parsedEnvironment.data.REA_ELECTRON_OBSERVE_ENABLED === "true"
278
- ? [
279
- permissionScope("electron_observe", electronFileRoots.value, {
280
- origins: electronEndpoints.value,
281
- network: "loopback",
282
- }),
283
- ]
284
- : []),
285
- ...(parsedEnvironment.data.REA_ARTIFACT_NATIVE_MOUNT_ENABLED === "true"
286
- ? [permissionScope("native_mount", [], { mount: true })]
287
- : []),
288
- ...(parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_ENABLED === "true"
289
- ? [
290
- permissionScope("javascript_replay", javascriptReplayRoots.value, {
291
- executables: [
292
- parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_NODE_PATH,
293
- parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_BWRAP_PATH,
294
- parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH,
295
- parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH,
296
- parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_SHELL_PATH,
297
- ],
298
- network: "none",
299
- mount: true,
300
- }),
301
- ]
302
- : []),
303
- ...(parsedEnvironment.data.REA_MANAGED_RUNTIME_ENABLED === "true"
304
- ? [
305
- permissionScope("managed_runtime", managedRuntimeRoots.value, {
306
- executables: [
307
- parsedEnvironment.data.REA_MANAGED_RUNTIME_EXECUTABLE_PATH,
308
- ],
309
- network: "none",
310
- }),
311
- ]
312
- : []),
313
- ];
314
- return ok({
315
- analysisProvider: parsedEnvironment.data.REA_ANALYSIS_PROVIDER,
316
- ghidraInstallDir: parsedEnvironment.data.GHIDRA_INSTALL_DIR,
317
- ghidraJavaHome: parsedEnvironment.data.JAVA_HOME,
318
- hopperLauncherPath: parsedEnvironment.data.HOPPER_LAUNCHER_PATH ??
319
- defaultHopperLauncherPath(),
320
- hopperTargetPath: parsedEnvironment.data.HOPPER_TARGET_PATH,
321
- hopperTargetKind: parsedEnvironment.data.HOPPER_TARGET_KIND,
322
- hopperLoaderArgs: loaderArgs.value,
323
- logLevel: parsedEnvironment.data.REA_LOG_LEVEL,
324
- processExecutionPolicy: {
325
- enabled: parsedEnvironment.data.REA_PROCESS_CAPTURE_ENABLED === "true",
326
- executableRoots: executableRoots.value,
327
- workingRoots: workingRoots.value,
328
- allowedEnvironment: allowedEnvironment.value,
329
- allowExternalNetwork: parsedEnvironment.data.REA_PROCESS_ALLOW_EXTERNAL_NETWORK === "true",
330
- },
331
- artifactNativeMountEnabled: parsedEnvironment.data.REA_ARTIFACT_NATIVE_MOUNT_ENABLED === "true",
332
- artifactIntegrityContinueEnabled: parsedEnvironment.data.REA_ARTIFACT_INTEGRITY_CONTINUE_ENABLED === "true",
333
- evidenceFilePolicy: filePolicy(evidenceRoots.value),
334
- investigationInputRoots: investigationInputRoots.value,
335
- analysisSnapshotFilePolicy: filePolicy(analysisSnapshotRoots.value),
336
- referenceSourcePolicy: {
337
- roots: referenceRoots.value,
338
- secretPatterns: secretPatterns.value,
339
- maxBytes: 16 * 1024 * 1024,
340
- maxEntries: 10_000,
341
- maxDepth: 32,
342
- maxPathBytes: 4_096,
343
- },
344
- browserObservationEnabled: parsedEnvironment.data.REA_BROWSER_OBSERVE_ENABLED === "true",
345
- browserCdpEndpoints: browserEndpoints.value,
346
- browserAllowedOrigins: browserOrigins.value,
347
- electronObservationEnabled: parsedEnvironment.data.REA_ELECTRON_OBSERVE_ENABLED === "true",
348
- electronCdpEndpoints: electronEndpoints.value,
349
- electronFileRoots: electronFileRoots.value,
350
- javascriptReplayPolicy: {
351
- enabled: parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_ENABLED === "true",
352
- roots: javascriptReplayRoots.value,
353
- nodePath: parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_NODE_PATH,
354
- bubblewrapPath: parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_BWRAP_PATH,
355
- systemdRunPath: parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH,
356
- systemctlPath: parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH,
357
- shellPath: parsedEnvironment.data.REA_JAVASCRIPT_REPLAY_SHELL_PATH,
358
- },
359
- managedRuntimePolicy: {
360
- enabled: parsedEnvironment.data.REA_MANAGED_RUNTIME_ENABLED === "true",
361
- roots: managedRuntimeRoots.value,
362
- executablePath: parsedEnvironment.data.REA_MANAGED_RUNTIME_EXECUTABLE_PATH,
363
- },
364
- permissionCeilings,
365
- administratorPermissionGrants: administratorGrants(permissionCeilings),
366
- permissionProjectRoot: parsedEnvironment.data.REA_PERMISSION_PROJECT_ROOT,
367
- permissionProjectStore: parsedEnvironment.data.REA_PERMISSION_PROJECT_STORE,
368
- });
369
- };
370
- const browserNetworkScope = (origins) => origins.every((origin) => {
371
- const hostname = new URL(origin).hostname;
372
- return isLiteralLoopbackHostname(hostname);
373
- })
374
- ? "loopback"
375
- : "external";
1
+ export { parseConfig } from "./config/parseConfig.js";
@@ -1,11 +1,77 @@
1
1
  import { applicationVersionComparisonResultSchema, compareApplicationVersionsInputSchema, } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
2
2
  import { applicationFeatureTraceResultSchema, traceApplicationFeatureInputSchema, } from "../domain/javascriptFeatureTraceSchemas.js";
3
3
  import { controlledReplayInputSchema, controlledReplayOutputSchema, } from "../domain/javascriptReplay.js";
4
+ import { nodeCharacterizationExecutionInputSchema, nodeCharacterizationExecutionOutputSchema, nodeCharacterizationPreparationInputSchema, nodeCharacterizationPreparationOutputSchema, } from "../domain/nodeRuntimeCharacterization.js";
5
+ import { reconstructionCoverageCommitInputSchema, reconstructionCoverageCommitOutputSchema, reconstructionCoverageQueryInputSchema, } from "../application/ReconstructionCoverageService.js";
6
+ import { reconstructionClosureResultSchema } from "../domain/reconstructionCoverage.js";
7
+ import { jsonObjectSchema } from "../domain/jsonValue.js";
4
8
  import { toolContractMetadata } from "./toolEffects.js";
5
9
  import { evidenceResultOf } from "./toolOutputSchemas.js";
6
10
  import { JAVASCRIPT_APPLICATION_VERSION_COMPARISON_EXAMPLE, JAVASCRIPT_FEATURE_TRACE_EXAMPLE, } from "./javascriptApplicationWorkflowExamples.js";
7
11
  const traceOutputSchema = evidenceResultOf(applicationFeatureTraceResultSchema);
8
12
  const comparisonOutputSchema = evidenceResultOf(applicationVersionComparisonResultSchema);
13
+ const HASH = "0".repeat(64);
14
+ const NODE_PREPARATION_EXAMPLE = jsonObjectSchema.parse({
15
+ preparation_approved: true,
16
+ selected_alias: "bundle",
17
+ expected_effect: "pure",
18
+ instrumentation: {
19
+ artifact_path: "/approved/bundle.js",
20
+ artifact_sha256: HASH,
21
+ selection: {
22
+ byte_start: 100,
23
+ byte_end: 120,
24
+ selected_sha256: HASH,
25
+ export_name: "selected",
26
+ },
27
+ },
28
+ replay: {
29
+ mode: "plan",
30
+ left: {
31
+ modules: [
32
+ {
33
+ alias: "bundle",
34
+ path: "/approved/bundle.js",
35
+ format: "commonjs-factory",
36
+ role: "module",
37
+ dependencies: {},
38
+ },
39
+ ],
40
+ entry_alias: "bundle",
41
+ entry_export: "selected",
42
+ },
43
+ cases: [{ case_id: "empty", arguments: [""] }],
44
+ approved: false,
45
+ },
46
+ });
47
+ const COVERAGE_WORKSPACE_EXAMPLE = jsonObjectSchema.parse({
48
+ schema_version: 1,
49
+ workspace_id: `rcw_${HASH}`,
50
+ name: "replacement",
51
+ revision: 1,
52
+ previous_revision_sha256: null,
53
+ revision_sha256: HASH,
54
+ evidence_bundle: {
55
+ bundle_version: 2,
56
+ artifacts: [],
57
+ providers: [],
58
+ environments: [],
59
+ scenarios: [],
60
+ captures: [],
61
+ unknowns: [],
62
+ records: [],
63
+ },
64
+ artifacts: [],
65
+ surfaces: [],
66
+ owners: [],
67
+ claims: [],
68
+ verifier_contracts: [],
69
+ verifier_results: [],
70
+ residual_unknown_ids: [],
71
+ contradictions: [],
72
+ package_proofs: [],
73
+ boundaries: [],
74
+ });
9
75
  /** Provider-neutral graph workflow contracts shared by MCP and CLI adapters. */
10
76
  export const APPLICATION_TOOL_CONTRACTS = [
11
77
  {
@@ -88,4 +154,72 @@ export const APPLICATION_TOOL_CONTRACTS = [
88
154
  },
89
155
  ],
90
156
  },
157
+ {
158
+ name: "prepare_node_characterization",
159
+ ...toolContractMetadata("prepare_node_characterization"),
160
+ description: "Prepare a hash-bound Node/JavaScript characterization plan and deterministic reversible export transformation without executing target code. The exact source, selected byte range, runtime closure, sandbox profile, cases, and limits are committed for separate execution approval.",
161
+ kind: "application",
162
+ inputSchema: nodeCharacterizationPreparationInputSchema,
163
+ outputSchema: nodeCharacterizationPreparationOutputSchema,
164
+ examples: [
165
+ {
166
+ title: "Prepare one exact bundled callable characterization",
167
+ input: NODE_PREPARATION_EXAMPLE,
168
+ },
169
+ ],
170
+ },
171
+ {
172
+ name: "execute_node_characterization",
173
+ ...toolContractMetadata("execute_node_characterization"),
174
+ description: "Recompute and execute one separately approved exact Node characterization plan in the owned controlled-replay boundary. Returns transformation, replay, cleanup, and provider-neutral characterization Evidence v2; stale plans fail before execution.",
175
+ kind: "application",
176
+ inputSchema: nodeCharacterizationExecutionInputSchema,
177
+ outputSchema: nodeCharacterizationExecutionOutputSchema,
178
+ examples: [
179
+ {
180
+ title: "Execute one approved exact characterization plan",
181
+ input: {
182
+ execution_approved: true,
183
+ approved_plan_sha256: HASH,
184
+ preparation: NODE_PREPARATION_EXAMPLE,
185
+ },
186
+ },
187
+ ],
188
+ },
189
+ {
190
+ name: "commit_reconstruction_coverage",
191
+ ...toolContractMetadata("commit_reconstruction_coverage"),
192
+ description: "Atomically commit one canonical evidence-backed reconstruction coverage workspace revision under an approved root. CAS revisions reject lost updates; every Evidence and residual-unknown reference must resolve in the embedded canonical bundle.",
193
+ kind: "application",
194
+ inputSchema: reconstructionCoverageCommitInputSchema,
195
+ outputSchema: reconstructionCoverageCommitOutputSchema,
196
+ examples: [
197
+ {
198
+ title: "Commit the first canonical coverage revision",
199
+ input: {
200
+ approved: true,
201
+ workspace_path: "/approved/coverage.json",
202
+ expected_revision: null,
203
+ workspace: COVERAGE_WORKSPACE_EXAMPLE,
204
+ },
205
+ },
206
+ ],
207
+ },
208
+ {
209
+ name: "query_reconstruction_coverage",
210
+ ...toolContractMetadata("query_reconstruction_coverage"),
211
+ description: "Evaluate one named reconstruction boundary from a canonical coverage workspace. Missing ownership or inventory is partial; stale, weak, truncated, skipped, or unresolved proof is unknown; contradictions, failed proof, missing owners, and authority routing fail closed.",
212
+ kind: "application",
213
+ inputSchema: reconstructionCoverageQueryInputSchema,
214
+ outputSchema: reconstructionClosureResultSchema,
215
+ examples: [
216
+ {
217
+ title: "Evaluate one replacement boundary",
218
+ input: {
219
+ workspace_path: "/approved/coverage.json",
220
+ boundary_id: "replacement.cli",
221
+ },
222
+ },
223
+ ],
224
+ },
91
225
  ];
@@ -125,7 +125,7 @@ export const MANAGED_TOOL_CONTRACTS = [
125
125
  {
126
126
  name: "inspect_managed_members",
127
127
  ...toolContractMetadata("inspect_managed_members"),
128
- description: "Inspect bounded PE/CLI metadata members, signatures, method body IL hashes, exception regions, call edges, and field-access anchors without loading or executing target code. Metadata tokens are reported as build-local coordinates bound to the artifact SHA-256 and MVID.",
128
+ description: "Inspect bounded PE/CLI metadata members, signatures, raw CIL hashes, limited member-result-v1 decoded-instruction-tuple hashes, separately reported exception regions, call edges, and field-access anchors without loading or executing target code. Metadata tokens are reported as build-local coordinates bound to the artifact SHA-256 and MVID; the v1 tuple hash does not resolve them or fully commit control flow.",
129
129
  kind: "managed-provider",
130
130
  inputSchema: managedMemberInputSchema,
131
131
  outputSchema: memberOutputSchema,
@@ -111,7 +111,7 @@ export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [
111
111
  {
112
112
  name: "compare_managed_members",
113
113
  ...toolContractMetadata("compare_managed_members"),
114
- description: "Compare two authenticated inspect_managed_members Evidence records using unique-only CIL/signature and structural method-shape tiers. Names are reported as observations but are not used as a matching basis; metadata tokens are remapped as build-local coordinates bound to each artifact SHA-256 and MVID.",
114
+ description: "Compare two authenticated inspect_managed_members Evidence records using unique-only decoded-CIL-v1/signature and structural method-shape tiers. Names are reported as observations but are not used as a matching basis; metadata tokens remain build-local coordinates bound to each artifact SHA-256 and MVID, and the v1 tuple digest does not itself remap them.",
115
115
  kind: "application",
116
116
  inputSchema: compareManagedMembersReferenceInputSchema,
117
117
  outputSchema: comparisonOutputSchema,
@@ -147,7 +147,7 @@ export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [
147
147
  {
148
148
  name: "import_managed_reconstruction",
149
149
  ...toolContractMetadata("import_managed_reconstruction"),
150
- description: "Import decompiler-produced managed reconstruction against authenticated inspect_managed_members Evidence. The workflow locks each method to artifact SHA-256, MVID, metadata token, signature hash, and normalized IL hash, records the decompiler identity and options, and marks C# or pseudocode as analyst inference rather than canonical byte observation.",
150
+ description: "Import decompiler-produced managed reconstruction against authenticated inspect_managed_members Evidence. The workflow locks each method to artifact SHA-256, MVID, metadata token, signature hash, and the limited member-result-v1 decoded-IL tuple hash, records the decompiler identity and options, and marks C# or pseudocode as analyst inference rather than canonical byte observation.",
151
151
  kind: "application",
152
152
  inputSchema: managedReconstructionReferenceInputSchema,
153
153
  outputSchema: reconstructionOutputSchema,
@@ -166,7 +166,7 @@ export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [
166
166
  {
167
167
  name: "plan_managed_runtime_correlation",
168
168
  ...toolContractMetadata("plan_managed_runtime_correlation"),
169
- description: "Prepare a separately authorized managed runtime-correlation admission plan from authenticated inspect_managed_members Evidence. The operation is default-disabled, requires the managed_runtime permission ceiling and grant, locks the exact artifact SHA-256, MVID, method signature, and normalized IL shape, distinguishes attach/load/debugger/reflection/instrumentation effects, and records that no target code was executed.",
169
+ description: "Prepare a separately authorized managed runtime-correlation admission plan from authenticated inspect_managed_members Evidence. The operation is default-disabled, requires the managed_runtime permission ceiling and grant, locks the exact artifact SHA-256, MVID, method signature, and limited member-result-v1 decoded-IL tuple hash, distinguishes attach/load/debugger/reflection/instrumentation effects, and records that no target code was executed.",
170
170
  kind: "application",
171
171
  inputSchema: managedRuntimeCorrelationReferenceInputSchema,
172
172
  outputSchema: runtimeOutputSchema,
@@ -23,6 +23,8 @@ export const PROVIDER_REJECTION_CODES = [
23
23
  "target_kind_unsupported",
24
24
  "target_format_unsupported",
25
25
  "architecture_unsupported",
26
+ "target_role_unsupported",
27
+ "managed_target_unsupported",
26
28
  "open_options_invalid",
27
29
  "version_unresolved",
28
30
  ];
@@ -125,8 +125,8 @@ export const OFFICIAL_TOOL_CONTRACTS = [
125
125
  })),
126
126
  official("procedure_pseudo_code", "Decompile one analyzed procedure by symbol name or provider-normalized address. Returns provider-specific pseudocode, never original source or cross-provider text equivalence, and may return null; request procedure_assembly when instruction precision matters.", z.object({ procedure, document })),
127
127
  official("resolve_containing_procedure", "Resolve an arbitrary address, including an interior instruction or exact external entry, to its provider-analyzed containing procedure. A negative result distinguishes outside segments from not in a procedure and is never guessed from nearby symbols.", z.object({ address, document })),
128
- official("search_procedures", "Search analyzed procedure names using literal matching by default or regex opt-in. Ghidra bounds literal work and rejects regex constructs, paths, candidates, or cumulative work outside its finite budgets. Results are deterministic and offset-paginated.", z.object(searchInput)),
129
- official("search_strings", "Search analyzed strings using literal matching by default or regex opt-in. Ghidra bounds literal work and rejects regex constructs, paths, candidates, or cumulative work outside its finite budgets. Results are deterministic, offset-paginated, and explicitly truncated.", z.object(searchInput)),
128
+ official("search_procedures", "Search analyzed procedure names using literal matching by default or regex opt-in. Providers bound search work and reject regex constructs, paths, candidates, or cumulative work outside their finite budgets. Results are deterministic and offset-paginated.", z.object(searchInput)),
129
+ official("search_strings", "Search analyzed strings using literal matching by default or regex opt-in. Providers bound search work and reject regex constructs, paths, candidates, or cumulative work outside their finite budgets. Results are deterministic, offset-paginated, and explicitly truncated.", z.object(searchInput)),
130
130
  official("set_address_name", "Assign an analyst name to one hexadecimal address and report Hopper's boolean result. This mutates analysis metadata; read it back with address_name before relying on it.", z.object({ address, name: z.string(), document })),
131
131
  official("set_addresses_names", "Assign analyst names to an address/name map and return per-address success booleans. This mutates analysis metadata; use for bounded batches and verify failures individually.", z.object({ names: z.record(z.string(), z.string()), document })),
132
132
  official("set_bookmark", "Create or replace a bookmark at a hexadecimal address. This mutates navigation metadata; verify with list_bookmarks and do not treat bookmarks as binary evidence.", z.object({ address, name: z.string().optional(), document })),
@@ -99,6 +99,20 @@ export const TOOL_EFFECTS = {
99
99
  writesFilesystem: true,
100
100
  launchesProcess: true,
101
101
  }),
102
+ prepare_node_characterization: effects({
103
+ mutatesSession: true,
104
+ launchesProcess: true,
105
+ }),
106
+ execute_node_characterization: effects({
107
+ mutatesSession: true,
108
+ writesFilesystem: true,
109
+ launchesProcess: true,
110
+ }),
111
+ commit_reconstruction_coverage: effects({
112
+ writesFilesystem: true,
113
+ mutatesSession: true,
114
+ }),
115
+ query_reconstruction_coverage: effects({ mutatesSession: true }),
102
116
  open_binary: effects({ mutatesSession: true, launchesProcess: true }),
103
117
  close_binary: effects({
104
118
  mutatesSession: true,