rea-agents 2.3.0 → 2.5.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 (209) hide show
  1. package/README.md +80 -18
  2. package/bridge/ghidra/ReaGhidraBridge.java +48 -1
  3. package/bridge/hopper_bridge.py +259 -24
  4. package/dist/application/AnalysisClientCleanup.js +14 -0
  5. package/dist/application/ApplicationWorkflowEvidenceResolver.js +31 -13
  6. package/dist/application/ArtifactExtraction.js +5 -1
  7. package/dist/application/ArtifactGraphConstruction.js +3 -15
  8. package/dist/application/ArtifactInventory/classify.js +5 -1
  9. package/dist/application/ArtifactInventory/reader.js +2 -0
  10. package/dist/application/BinarySession.js +15 -4
  11. package/dist/application/BinarySessionStatus.js +32 -1
  12. package/dist/application/BrowserEvidence.js +14 -0
  13. package/dist/application/BrowserScenarioCapturePort.js +1 -0
  14. package/dist/application/BrowserScenarioCaptureService.js +53 -0
  15. package/dist/application/BrowserScenarioEvidence.js +40 -0
  16. package/dist/application/CallPathTracing.js +160 -0
  17. package/dist/application/CapabilityInventory.js +79 -15
  18. package/dist/application/CompositeProvider.js +10 -1
  19. package/dist/application/DirectAnalysis.js +7 -2
  20. package/dist/application/EnhancedLiteralTracing.js +118 -0
  21. package/dist/application/EnhancedTools.js +35 -121
  22. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +13 -0
  23. package/dist/application/JavaScriptApplicationWorkflowService.js +27 -1
  24. package/dist/application/JavaScriptRuntimeObservationEvidence.js +34 -0
  25. package/dist/application/JavaScriptRuntimeObservationPort.js +1 -0
  26. package/dist/application/JavaScriptRuntimeObservationService.js +46 -0
  27. package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +147 -0
  28. package/dist/application/JavaScriptSemanticGraphBuilder.js +34 -6
  29. package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +156 -0
  30. package/dist/application/JavaScriptSemanticGraphConstruction.js +2 -2
  31. package/dist/application/JavaScriptSemanticGraphDataProjection.js +203 -0
  32. package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +25 -0
  33. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +129 -8
  34. package/dist/application/JavaScriptSemanticGraphObjectProjection.js +81 -0
  35. package/dist/application/JavaScriptSemanticGraphProjection.js +14 -7
  36. package/dist/application/JavaScriptSemanticGraphResourceProjection.js +59 -0
  37. package/dist/application/JavaScriptSemanticGraphValueProjection.js +77 -0
  38. package/dist/application/ProcessCaptureEnvironment.js +26 -0
  39. package/dist/application/ProcessCaptureLifecycle.js +1 -0
  40. package/dist/application/ProcessCheckpoints.js +5 -0
  41. package/dist/application/ProcessHarness.js +45 -34
  42. package/dist/application/ProcessNormalization.js +6 -0
  43. package/dist/application/ProcessReactiveCoordinator.js +10 -3
  44. package/dist/application/ProcessReactiveEffects.js +15 -1
  45. package/dist/application/ProcessReactiveHarness.js +100 -0
  46. package/dist/application/ProcessReactiveObservations.js +101 -16
  47. package/dist/application/ProjectPermissionStore.js +1 -0
  48. package/dist/application/ReconstructionObligationAuthority.js +72 -0
  49. package/dist/application/ReconstructionObligationCandidates.js +265 -0
  50. package/dist/application/ReconstructionObligationLedgerDiagnostics.js +47 -0
  51. package/dist/application/ReconstructionObligationLedgerEvaluation.js +263 -0
  52. package/dist/application/ReconstructionObligationLedgerProjection.js +86 -0
  53. package/dist/application/ReconstructionObligationLedgerService.js +72 -0
  54. package/dist/application/ReconstructionObligationOriginalCases.js +33 -0
  55. package/dist/application/ReconstructionObligationPolicies.js +132 -0
  56. package/dist/application/ReconstructionReadinessService.js +48 -0
  57. package/dist/artifacts/ArtifactProvider.js +87 -22
  58. package/dist/browser/BrowserScenarioSecrets.js +53 -0
  59. package/dist/browser/BrowserScenarioSessionPort.js +1 -0
  60. package/dist/browser/CdpBrowserProvider.js +2 -2
  61. package/dist/browser/CdpCaptureDocuments.js +57 -0
  62. package/dist/browser/CdpCaptureStorage.js +71 -29
  63. package/dist/browser/CdpCaptureStorageFingerprints.js +328 -0
  64. package/dist/browser/CdpEndpoint.js +8 -6
  65. package/dist/browser/CdpPageCapture.js +2 -0
  66. package/dist/browser/JavaScriptRuntimeScope.js +38 -0
  67. package/dist/browser/PlaywrightBrowserScenarioProvider.js +253 -0
  68. package/dist/browser/PlaywrightExecutionBoundary.js +42 -0
  69. package/dist/browser/PlaywrightScenarioActions.js +62 -0
  70. package/dist/browser/PlaywrightScenarioArtifacts.js +238 -0
  71. package/dist/browser/PlaywrightScenarioBrowser.js +144 -0
  72. package/dist/browser/PlaywrightScenarioEvents.js +301 -0
  73. package/dist/browser/PlaywrightScenarioSession.js +300 -0
  74. package/dist/browser/V8InspectorCaptureProjection.js +110 -0
  75. package/dist/browser/V8InspectorEndpoint.js +72 -0
  76. package/dist/browser/V8InspectorProvider.js +267 -0
  77. package/dist/catalogIdentity.js +8 -0
  78. package/dist/cli/artifactCommands.js +39 -0
  79. package/dist/cli/coreAnalysisCommands.js +37 -0
  80. package/dist/cli.js +4 -0
  81. package/dist/cliApplicationCommands.js +30 -2
  82. package/dist/cliBrowserAdvancedCommands.js +17 -5
  83. package/dist/cliBrowserCommands.js +1 -0
  84. package/dist/cliBrowserScenarioCommands.js +43 -0
  85. package/dist/cliCommandNames.js +8 -0
  86. package/dist/cliJavaScriptRuntimeCommands.js +164 -0
  87. package/dist/cliObservationOptions.js +4 -0
  88. package/dist/cliPolicyCommands.js +1 -0
  89. package/dist/config/environment.js +12 -0
  90. package/dist/config/parseConfig.js +88 -17
  91. package/dist/contracts/analysisSearchContract.js +14 -0
  92. package/dist/contracts/applicationToolContracts.js +86 -2
  93. package/dist/contracts/applicationWorkflowInputContracts.js +18 -0
  94. package/dist/contracts/artifactToolContracts.js +22 -0
  95. package/dist/contracts/browserProviderToolContracts.js +7 -0
  96. package/dist/contracts/browserScenarioToolContracts.js +81 -0
  97. package/dist/contracts/browserToolContracts.js +88 -98
  98. package/dist/contracts/enhancedInputs.js +25 -6
  99. package/dist/contracts/functionInstructionContract.js +8 -0
  100. package/dist/contracts/hopperMemoryContracts.js +22 -0
  101. package/dist/contracts/javascriptApplicationWorkflowExamples.js +42 -0
  102. package/dist/contracts/javascriptRuntimeObservationToolContracts.js +58 -0
  103. package/dist/contracts/reconstructionReadinessExample.js +436 -0
  104. package/dist/contracts/toolContractExamples.js +5 -0
  105. package/dist/contracts/toolContractTypes.js +1 -0
  106. package/dist/contracts/toolContracts.js +13 -21
  107. package/dist/contracts/toolEffects.js +21 -0
  108. package/dist/contracts/toolOutputSchemaGroups.js +70 -20
  109. package/dist/contracts/toolOutputSchemaPrimitives.js +40 -0
  110. package/dist/domain/analysisErrorProjection.js +8 -0
  111. package/dist/domain/analysisSnapshot.js +2 -0
  112. package/dist/domain/artifactGraph.js +2 -0
  113. package/dist/domain/artifactInspection.js +347 -0
  114. package/dist/domain/binaryTarget.js +3 -6
  115. package/dist/domain/browserCaptureComparison.js +82 -0
  116. package/dist/domain/browserObservation.js +8 -1
  117. package/dist/domain/browserObservationErrors.js +1 -0
  118. package/dist/domain/browserObservationSchemas.js +26 -0
  119. package/dist/domain/browserScenario.js +165 -0
  120. package/dist/domain/browserScenarioCapture.js +57 -0
  121. package/dist/domain/browserScenarioCaptureValues.js +204 -0
  122. package/dist/domain/browserScenarioDiff.js +324 -0
  123. package/dist/domain/browserScenarioDiffValues.js +157 -0
  124. package/dist/domain/browserScenarioNormalization.js +45 -0
  125. package/dist/domain/browserScenarioValues.js +372 -0
  126. package/dist/domain/evidence.js +2 -0
  127. package/dist/domain/hopperValues.js +10 -0
  128. package/dist/domain/javascriptRuntimeObservation.js +170 -0
  129. package/dist/domain/javascriptRuntimeReconciliationParsing.js +120 -2
  130. package/dist/domain/javascriptRuntimeReconciliationResult.js +3 -3
  131. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +2 -2
  132. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  133. package/dist/domain/javascriptSemanticAnalysis.js +5 -4
  134. package/dist/domain/javascriptSemanticAsyncEffects.js +253 -0
  135. package/dist/domain/javascriptSemanticChildProcesses.js +237 -0
  136. package/dist/domain/javascriptSemanticDataEffectHelpers.js +125 -0
  137. package/dist/domain/javascriptSemanticDataEffects.js +284 -0
  138. package/dist/domain/javascriptSemanticDerivedAnalysis.js +41 -0
  139. package/dist/domain/javascriptSemanticFingerprints.js +174 -0
  140. package/dist/domain/javascriptSemanticIr.js +21 -1
  141. package/dist/domain/javascriptSemanticObjects.js +115 -0
  142. package/dist/domain/javascriptSemanticPromises.js +290 -0
  143. package/dist/domain/javascriptSemanticResources.js +136 -0
  144. package/dist/domain/javascriptStaticAnalysis.js +4 -3
  145. package/dist/domain/javascriptStaticAnalysisBundler.js +38 -0
  146. package/dist/domain/javascriptStaticAnalysisCalls.js +23 -1
  147. package/dist/domain/javascriptStaticAnalysisHelpers.js +8 -0
  148. package/dist/domain/processCapture.js +71 -1
  149. package/dist/domain/processCaptureReactiveValidation.js +175 -0
  150. package/dist/domain/processCaptureValidation.js +2 -0
  151. package/dist/domain/processObservation.js +15 -6
  152. package/dist/domain/processReactiveRuntime.js +21 -10
  153. package/dist/domain/processReactiveScenario.js +1 -0
  154. package/dist/domain/processReactiveTransition.js +17 -10
  155. package/dist/domain/processScenario.js +21 -0
  156. package/dist/domain/providerCleanupError.js +11 -0
  157. package/dist/domain/reconstructionObligationLedgerSchemas.js +278 -0
  158. package/dist/domain/reconstructionReadiness.js +121 -0
  159. package/dist/domain/reconstructionReadinessFindingHelpers.js +17 -0
  160. package/dist/domain/reconstructionReadinessIntegrityFindings.js +118 -0
  161. package/dist/domain/reconstructionReadinessJourneyFindings.js +193 -0
  162. package/dist/domain/reconstructionReadinessSchemas.js +240 -0
  163. package/dist/domain/sourceToBundleComparison.js +335 -0
  164. package/dist/domain/sourceToBundleComparisonSchemas.js +133 -0
  165. package/dist/domain/sourceToBundleSignals.js +202 -0
  166. package/dist/domain/webCaptureDiff.js +141 -27
  167. package/dist/domain/webScreenshot.js +1 -1
  168. package/dist/domain/zipPackageFormat.js +20 -0
  169. package/dist/generatedPackageMetadata.js +1 -1
  170. package/dist/ghidra/GhidraDefaults.js +1 -1
  171. package/dist/ghidra/GhidraFunctionValues.js +13 -1
  172. package/dist/ghidra/GhidraProviderCapabilities.js +7 -0
  173. package/dist/hopper/HopperCleanup.js +158 -0
  174. package/dist/hopper/HopperClient.js +69 -99
  175. package/dist/hopper/HopperProvider.js +20 -1
  176. package/dist/hopper/HopperRequestQueue.js +187 -0
  177. package/dist/hopper/HopperResponseStream.js +46 -0
  178. package/dist/hopper/protocol.js +1 -0
  179. package/dist/main/transport.js +24 -24
  180. package/dist/main.js +6 -0
  181. package/dist/mcpDoctor.js +25 -2
  182. package/dist/native/NativeMacOSProvider.js +1 -0
  183. package/dist/process/ProcessCommandIdentity.js +19 -0
  184. package/dist/process/ProcessOwnership.js +11 -8
  185. package/dist/server/DynamicToolAvailability.js +70 -0
  186. package/dist/server/createServer.js +46 -1
  187. package/dist/server/lifecycleProgress.js +10 -0
  188. package/dist/server/permissionFailure.js +12 -0
  189. package/dist/server/registerApplicationTools/compareSourceToBundle.js +35 -0
  190. package/dist/server/registerApplicationTools/helpers.js +11 -7
  191. package/dist/server/registerApplicationTools/obligationLedger.js +27 -0
  192. package/dist/server/registerApplicationTools/readiness.js +55 -0
  193. package/dist/server/registerApplicationTools.js +6 -0
  194. package/dist/server/registerArtifactTools.js +9 -1
  195. package/dist/server/registerBrowserScenarioTool.js +25 -0
  196. package/dist/server/registerBrowserTools.js +2 -2
  197. package/dist/server/registerCloseLifecycleTool.js +57 -0
  198. package/dist/server/registerEnhancedTools.js +16 -5
  199. package/dist/server/registerEvidenceResources.js +4 -0
  200. package/dist/server/registerEvidenceTools.js +9 -2
  201. package/dist/server/registerJavaScriptRuntimeObservationTools.js +37 -0
  202. package/dist/server/registerReconstructionObligationLedgerResource.js +39 -0
  203. package/dist/server/registerReconstructionReadinessResource.js +39 -0
  204. package/dist/server/registerSessionStatusTool.js +11 -8
  205. package/dist/server/registerSessionTools.js +11 -57
  206. package/dist/server/sessionAvailabilityPolicy.js +10 -8
  207. package/package.json +12 -6
  208. package/skills/reverse-engineer-anything/SKILL.md +4 -3
  209. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +2 -2
@@ -0,0 +1,436 @@
1
+ import { createEvidence } from "../domain/evidence.js";
2
+ import { createEvidenceBundle } from "../domain/evidenceBundle.js";
3
+ import { READINESS_REQUIRED_CHECKS, READINESS_STAGE_IDS, } from "../domain/reconstructionReadinessJourneyFindings.js";
4
+ const HASH = "a".repeat(64);
5
+ const sourceEvidence = (variant) => createEvidence(undefined, {
6
+ id: "rea-readiness-fixture",
7
+ name: "REA readiness fixture",
8
+ version: "1",
9
+ }, {
10
+ predicateType: "rea.reconstruction-readiness-fixture/v1",
11
+ operation: "run_reconstruction_readiness_fixture",
12
+ parameters: { variant },
13
+ result: { passed: true, variant },
14
+ confidence: "observed",
15
+ authority: "controlled-replay",
16
+ });
17
+ const SOURCE = sourceEvidence("authority");
18
+ const CONTRADICTING_SOURCE = sourceEvidence("contradiction");
19
+ const EVIDENCE_ID = SOURCE.evidence_id;
20
+ const CASES = [
21
+ "positive",
22
+ "negative",
23
+ "malformed",
24
+ "cancellation",
25
+ "teardown",
26
+ ];
27
+ const FIXTURES = [
28
+ "native",
29
+ "javascript-cli",
30
+ "electron",
31
+ "incomplete-reconstruction",
32
+ "broken-runtime",
33
+ ];
34
+ const STATUSES = [
35
+ "unowned",
36
+ "characterized",
37
+ "implemented",
38
+ "verified",
39
+ "contradicted",
40
+ "blocked",
41
+ "out-of-scope",
42
+ "unknown",
43
+ ];
44
+ const LAYERS = [
45
+ "cli",
46
+ "protocol",
47
+ "electron",
48
+ "persistence",
49
+ "process",
50
+ "runtime",
51
+ "packaging",
52
+ "native-abi",
53
+ "application",
54
+ "other",
55
+ ];
56
+ const EVIDENCE_STATES = [
57
+ "candidate",
58
+ "observed",
59
+ "reviewed",
60
+ "unknown",
61
+ ];
62
+ /** Complete synthetic input shared by docs, tests, CLI, MCP, and verifier. */
63
+ export const RECONSTRUCTION_READINESS_EXAMPLE = {
64
+ schema_version: 1,
65
+ identity: {
66
+ cli_version: "2.4.0",
67
+ server_version: "2.4.0",
68
+ catalog_digest: HASH,
69
+ skill_digest: HASH,
70
+ versions: [
71
+ {
72
+ component: "rea-cli",
73
+ version: "2.4.0",
74
+ digest: HASH,
75
+ state: "current",
76
+ remediation: null,
77
+ },
78
+ {
79
+ component: "rea-server",
80
+ version: "2.3.0",
81
+ digest: "b".repeat(64),
82
+ state: "stale",
83
+ remediation: "Restart the connected MCP server.",
84
+ },
85
+ {
86
+ component: "rea-server",
87
+ version: "2.4.0",
88
+ digest: HASH,
89
+ state: "current",
90
+ remediation: null,
91
+ },
92
+ ],
93
+ providers: [
94
+ {
95
+ provider_id: "javascript-application",
96
+ version: "1",
97
+ digest: HASH,
98
+ state: "available",
99
+ reason_code: null,
100
+ },
101
+ {
102
+ provider_id: "broken-runtime-probe",
103
+ version: null,
104
+ digest: null,
105
+ state: "broken-host",
106
+ reason_code: "host-runtime-linker-failure",
107
+ },
108
+ ],
109
+ },
110
+ client: {
111
+ name: "synthetic-mcp-client",
112
+ version: "1",
113
+ negotiated_capabilities: ["elicitation", "progress", "resources"],
114
+ },
115
+ capabilities: [
116
+ {
117
+ capability_id: "analyze-javascript-application",
118
+ available: true,
119
+ bounded: true,
120
+ side_effect: "reads-target",
121
+ authority_scopes: ["investigation-input"],
122
+ limits: [{ name: "max-ast-nodes", value: 2_000_000, unit: "count" }],
123
+ unavailable_reason: null,
124
+ },
125
+ ],
126
+ fixtures: FIXTURES.map((kind) => ({
127
+ fixture_id: `fixture.${kind}`,
128
+ kind,
129
+ artifact_sha256: HASH,
130
+ environment_id: "environment.synthetic",
131
+ deliberate_faults: [`fault.${kind}`],
132
+ })),
133
+ workflow_candidates: FIXTURES.map((kind) => ({
134
+ fixture_id: `fixture.${kind}`,
135
+ workflow_id: `workflow.${kind}`,
136
+ provider_id: kind === "broken-runtime" ? null : `provider.${kind}`,
137
+ selected: true,
138
+ invoked: true,
139
+ compatibility: "compatible",
140
+ reason_code: "compatible-artifact-family",
141
+ })),
142
+ grants: [
143
+ {
144
+ grant_id: "grant.denied",
145
+ scope: "process-capture",
146
+ decision: "denied",
147
+ launched_process: false,
148
+ evidence_ids: [EVIDENCE_ID],
149
+ },
150
+ {
151
+ grant_id: "grant.session",
152
+ scope: "process-capture",
153
+ decision: "granted",
154
+ launched_process: true,
155
+ evidence_ids: [EVIDENCE_ID],
156
+ },
157
+ ],
158
+ evidence_bundle: createEvidenceBundle([SOURCE, CONTRADICTING_SOURCE]),
159
+ comparisons: [
160
+ {
161
+ comparison_id: "comparison.concurrent",
162
+ verdict: "equivalent",
163
+ schedule_semantics: "partial-order",
164
+ concurrent: true,
165
+ truncated: false,
166
+ unavailable_authority: false,
167
+ unstable: false,
168
+ deliberate_divergence_ref: null,
169
+ divergence_refs: [],
170
+ contradiction_ids: [],
171
+ evidence_ids: [EVIDENCE_ID],
172
+ },
173
+ {
174
+ comparison_id: "comparison.divergence",
175
+ verdict: "different",
176
+ schedule_semantics: "finite-traces",
177
+ concurrent: true,
178
+ truncated: false,
179
+ unavailable_authority: false,
180
+ unstable: false,
181
+ deliberate_divergence_ref: "/events/primary",
182
+ divergence_refs: ["/events/primary"],
183
+ contradiction_ids: [],
184
+ evidence_ids: [EVIDENCE_ID],
185
+ },
186
+ {
187
+ comparison_id: "comparison.contradicted",
188
+ verdict: "unknown",
189
+ schedule_semantics: "finite-traces",
190
+ concurrent: false,
191
+ truncated: false,
192
+ unavailable_authority: false,
193
+ unstable: false,
194
+ deliberate_divergence_ref: null,
195
+ divergence_refs: [],
196
+ contradiction_ids: ["contradiction.artifact"],
197
+ evidence_ids: [EVIDENCE_ID],
198
+ },
199
+ ],
200
+ contradictions: [
201
+ {
202
+ contradiction_id: "contradiction.artifact",
203
+ declared_sha256: HASH,
204
+ observed_sha256: "b".repeat(64),
205
+ policy: "record-and-continue",
206
+ affected_comparison_ids: ["comparison.contradicted"],
207
+ evidence_ids: [EVIDENCE_ID, CONTRADICTING_SOURCE.evidence_id],
208
+ },
209
+ ],
210
+ obligation_ledger: {
211
+ schema: "ReconstructionObligationLedger",
212
+ schema_version: 1,
213
+ ledger_id: `rol_${HASH}`,
214
+ closure_digest: HASH,
215
+ status: "ready",
216
+ coverage: {
217
+ status: "complete",
218
+ truncated: false,
219
+ omitted_count: 0,
220
+ max_obligations: 100,
221
+ },
222
+ summary: {
223
+ total: 1,
224
+ required: 1,
225
+ verified: 1,
226
+ required_open: 0,
227
+ by_status: STATUSES.map((key) => ({
228
+ key,
229
+ count: key === "verified" ? 1 : 0,
230
+ })),
231
+ by_application_layer: LAYERS.map((key) => ({
232
+ key,
233
+ count: key === "process" ? 1 : 0,
234
+ })),
235
+ by_evidence_authority: EVIDENCE_STATES.map((key) => ({
236
+ key,
237
+ count: key === "observed" ? 1 : 0,
238
+ })),
239
+ },
240
+ reports: {
241
+ missing_owner_obligation_ids: [],
242
+ missing_verifier_obligation_ids: [],
243
+ contradicted_obligation_ids: [],
244
+ residual_unknown_ids: [],
245
+ },
246
+ ownership_graph: [
247
+ {
248
+ obligation_id: "obl.readiness",
249
+ module_path: "src/readiness.ts",
250
+ symbol: "runReadiness",
251
+ },
252
+ ],
253
+ dependency_graph: [],
254
+ obligations: [
255
+ {
256
+ obligation_id: "obl.readiness",
257
+ obligation_version: 1,
258
+ title: "Preserve the packaged readiness fixture lifecycle",
259
+ origin: "reviewed",
260
+ application_layer: "process",
261
+ family: "packaged-process-lifecycle",
262
+ target: {
263
+ artifact_sha256: HASH,
264
+ application_node_id: null,
265
+ semantic_node_id: null,
266
+ location: "/fixture",
267
+ },
268
+ authority_references: [
269
+ {
270
+ evidence_id: EVIDENCE_ID,
271
+ authority: "controlled-replay",
272
+ state: "observed",
273
+ location: "/fixture",
274
+ },
275
+ ],
276
+ source_state: "observed",
277
+ observed_cases: CASES.map((kind) => ({
278
+ kind,
279
+ evidence_id: EVIDENCE_ID,
280
+ location: `/original/${kind}`,
281
+ })),
282
+ required: true,
283
+ required_case_kinds: [...CASES],
284
+ required_original_authority: "process",
285
+ required_fixture_authority: "packaged-process",
286
+ required_verifier_authority: "packaged-process",
287
+ requires_parser_type: false,
288
+ dependency_obligation_ids: [],
289
+ residual_unknown_ids: [],
290
+ unavailable_authority: [],
291
+ required_next_evidence: [],
292
+ binding: {
293
+ obligation_id: "obl.readiness",
294
+ owner: {
295
+ module_path: "src/readiness.ts",
296
+ symbol: "runReadiness",
297
+ owner_sha256: HASH,
298
+ },
299
+ parser_type: null,
300
+ original_cases: CASES.map((kind) => ({
301
+ kind,
302
+ evidence_id: EVIDENCE_ID,
303
+ location: `/original/${kind}`,
304
+ })),
305
+ fixtures: CASES.map((kind) => ({
306
+ fixture_id: `fixture.${kind}`,
307
+ case_kind: kind,
308
+ authority: "packaged-process",
309
+ evidence_ids: [EVIDENCE_ID],
310
+ })),
311
+ verifier: {
312
+ verifier_id: "verifier.readiness",
313
+ claim_id: "claim.readiness",
314
+ command: "npm run verify:readiness",
315
+ authority: "packaged-process",
316
+ status: "pass",
317
+ result_evidence_id: EVIDENCE_ID,
318
+ enumerated_obligation_ids: ["obl.readiness"],
319
+ nondeterminism: {
320
+ mode: "partial-order",
321
+ specification: "Startup precedes teardown.",
322
+ },
323
+ },
324
+ },
325
+ status: "verified",
326
+ diagnostics: [],
327
+ },
328
+ ],
329
+ evidence_links: [EVIDENCE_ID],
330
+ limitations: [],
331
+ },
332
+ operation_outcomes: [
333
+ {
334
+ sequence: 0,
335
+ operation: "inspect-artifact",
336
+ surface: "cli",
337
+ call_kind: "valid",
338
+ expected_success: true,
339
+ cli_exit_code: 0,
340
+ mcp_status: null,
341
+ error_code: null,
342
+ recovered: false,
343
+ evidence_ids: [EVIDENCE_ID],
344
+ },
345
+ {
346
+ sequence: 1,
347
+ operation: "inspect-artifact",
348
+ surface: "mcp",
349
+ call_kind: "valid",
350
+ expected_success: true,
351
+ cli_exit_code: null,
352
+ mcp_status: "success",
353
+ error_code: null,
354
+ recovered: false,
355
+ evidence_ids: [EVIDENCE_ID],
356
+ },
357
+ {
358
+ sequence: 2,
359
+ operation: "capture-process",
360
+ surface: "cli",
361
+ call_kind: "permission",
362
+ expected_success: false,
363
+ cli_exit_code: 2,
364
+ mcp_status: null,
365
+ error_code: "permission-required",
366
+ recovered: true,
367
+ evidence_ids: [EVIDENCE_ID],
368
+ },
369
+ {
370
+ sequence: 3,
371
+ operation: "capture-process",
372
+ surface: "mcp",
373
+ call_kind: "permission",
374
+ expected_success: false,
375
+ cli_exit_code: null,
376
+ mcp_status: "non-success",
377
+ error_code: "permission-required",
378
+ recovered: true,
379
+ evidence_ids: [EVIDENCE_ID],
380
+ },
381
+ ],
382
+ cleanup: [
383
+ {
384
+ run_id: "run.cancelled",
385
+ cancelled: true,
386
+ owned_resources_remaining: 0,
387
+ diagnostic_evidence_ids: [EVIDENCE_ID],
388
+ },
389
+ ],
390
+ closure_history: [
391
+ {
392
+ sequence: 0,
393
+ ledger_digest: "b".repeat(64),
394
+ status: "open",
395
+ required_open: 1,
396
+ newly_verified_obligation_ids: [],
397
+ evidence_ids: [EVIDENCE_ID],
398
+ },
399
+ {
400
+ sequence: 1,
401
+ ledger_digest: HASH,
402
+ status: "ready",
403
+ required_open: 0,
404
+ newly_verified_obligation_ids: ["obl.readiness"],
405
+ evidence_ids: [EVIDENCE_ID],
406
+ },
407
+ ],
408
+ delegation_checks: [
409
+ {
410
+ candidate_id: "candidate.reconstructed",
411
+ delegates_to_authority: false,
412
+ evidence_ids: [EVIDENCE_ID],
413
+ },
414
+ ],
415
+ replay: {
416
+ expected_source_digest: null,
417
+ deterministic: true,
418
+ tamper_detected: true,
419
+ stale_input_detected: true,
420
+ evidence_ids: [EVIDENCE_ID],
421
+ },
422
+ stages: READINESS_STAGE_IDS.map((stageId) => ({
423
+ stage_id: stageId,
424
+ required: true,
425
+ status: "pass",
426
+ capability_issue: null,
427
+ next_action: null,
428
+ evidence_ids: [EVIDENCE_ID],
429
+ checks: READINESS_REQUIRED_CHECKS[stageId].map((checkId) => ({
430
+ check_id: checkId,
431
+ status: "pass",
432
+ detail: `Synthetic conformance proved ${checkId}.`,
433
+ evidence_ids: [EVIDENCE_ID],
434
+ })),
435
+ })),
436
+ };
@@ -13,6 +13,9 @@ export const TOOL_EXAMPLE_OVERRIDES = {
13
13
  procedure_callees: { procedure: "main" },
14
14
  procedure_callers: { procedure: "main" },
15
15
  procedure_info: { procedure: "main" },
16
+ read_function_instructions: { procedure: "main" },
17
+ read_bytes: { address: "0x1000", length: 16 },
18
+ address_to_file_offset: { address: "0x1000" },
16
19
  procedure_references: { procedure: "main" },
17
20
  procedure_pseudo_code: { procedure: "main" },
18
21
  resolve_containing_procedure: { address: "0x1000" },
@@ -29,6 +32,8 @@ export const TOOL_EXAMPLE_OVERRIDES = {
29
32
  find_xrefs_to_name: { name: "malloc" },
30
33
  analyze_function: { procedure: "main" },
31
34
  trace_feature: { query: "license" },
35
+ find_code_for_string: { query: "authorization failed" },
36
+ trace_call_path: { start: "0x1000", goal: "0x1100" },
32
37
  open_binary: { path: "/tmp/fixture" },
33
38
  import_evidence_bundle: { path: "evidence.json" },
34
39
  capture_process_scenario: {
@@ -7,6 +7,7 @@ export const TOOL_KINDS = [
7
7
  "managed-provider",
8
8
  "browser-provider",
9
9
  "electron-provider",
10
+ "runtime-provider",
10
11
  "application",
11
12
  "session",
12
13
  ];
@@ -18,12 +18,16 @@ import { NATIVE_TOOL_CONTRACTS } from "./nativeToolContracts.js";
18
18
  import { ARTIFACT_TOOL_CONTRACTS } from "./artifactToolContracts.js";
19
19
  import { MANAGED_TOOL_CONTRACTS } from "./managedToolContracts.js";
20
20
  import { MANAGED_WORKFLOW_TOOL_CONTRACTS } from "./managedWorkflowToolContracts.js";
21
- import { BROWSER_TOOL_CONTRACTS } from "./browserToolContracts.js";
21
+ import { BROWSER_PROVIDER_TOOL_CONTRACTS } from "./browserProviderToolContracts.js";
22
22
  import { ELECTRON_TOOL_CONTRACTS } from "./electronToolContracts.js";
23
+ import { JAVASCRIPT_RUNTIME_OBSERVATION_TOOL_CONTRACTS } from "./javascriptRuntimeObservationToolContracts.js";
23
24
  import { APPLICATION_TOOL_CONTRACTS } from "./applicationToolContracts.js";
24
25
  import { closeBinaryInputSchema, openBinaryInputSchema, } from "./sessionLifecycleInputs.js";
25
26
  import { toolContractMetadata } from "./toolEffects.js";
26
27
  import { binarySessionInputSchema } from "./sessionStatusContract.js";
28
+ import { functionInstructionInputSchema } from "./functionInstructionContract.js";
29
+ import { HOPPER_MEMORY_TOOL_DEFINITIONS } from "./hopperMemoryContracts.js";
30
+ import { analysisSearchInput } from "./analysisSearchContract.js";
27
31
  export { binarySessionInputSchema } from "./sessionStatusContract.js";
28
32
  const document = z.string().optional().describe("The document name");
29
33
  const address = z
@@ -31,27 +35,10 @@ const address = z
31
35
  .describe("A provider-normalized address; default memory uses 0x-prefixed hexadecimal");
32
36
  const optionalAddress = address.optional();
33
37
  const procedure = z.string().describe("The procedure name or address");
34
- const searchPattern = z
35
- .string()
36
- .min(1)
37
- .max(256)
38
- .describe("The literal text or bounded regex pattern to search for");
39
- const caseSensitive = z
40
- .boolean()
41
- .default(false)
42
- .describe("Whether to match case");
43
38
  const pagination = {
44
39
  offset: z.number().int().min(0).default(0),
45
40
  limit: z.number().int().min(1).max(500).default(100),
46
41
  };
47
- const searchInput = {
48
- pattern: searchPattern,
49
- mode: z.enum(["literal", "regex"]).default("literal"),
50
- case_sensitive: caseSensitive,
51
- offset: z.number().int().min(0).default(0),
52
- limit: z.number().int().min(1).max(100).default(100),
53
- document,
54
- };
55
42
  const exampleInputSchema = z.record(z.string(), jsonValueSchema);
56
43
  const examplesFor = (name, inputSchema) => {
57
44
  const parsed = inputSchema.parse(TOOL_EXAMPLE_OVERRIDES[name] ?? {});
@@ -119,6 +106,8 @@ export const OFFICIAL_TOOL_CONTRACTS = [
119
106
  official("procedure_callees", "Return the provider's resolved direct callees for one procedure identified by symbol or address. Unresolved indirect calls may be absent; use analyze_function and typed references to preserve available edge uncertainty.", z.object({ procedure, document })),
120
107
  official("procedure_callers", "Return the provider's resolved direct callers for one procedure identified by symbol or address. Results reflect completed static analysis and may omit unresolved indirect references.", z.object({ procedure, document })),
121
108
  official("procedure_info", "Return bounded metadata for one procedure identified by symbol or address: entrypoint, signature, locals, size, and block count. Follow with decompilation or assembly for behavior.", z.object({ procedure, document })),
109
+ official("read_function_instructions", "Read one offset-paginated window of raw instructions for an analyzed procedure without decompilation, caller discovery, or whole-program string/name scans. Use this fast path for instruction-level orientation; follow next_offset when truncated.", functionInstructionInputSchema),
110
+ ...HOPPER_MEMORY_TOOL_DEFINITIONS.map(({ name, description, inputSchema }) => official(name, description, inputSchema)),
122
111
  official("procedure_references", "Return a bounded set of raw incoming or outgoing reference edges for one procedure. Endpoint procedures are resolved only from provider containment; Ghidra preserves observed reference kinds while providers without kind authority mark them unavailable.", z.object({
123
112
  procedure,
124
113
  direction: z.enum(["incoming", "outgoing"]).default("outgoing"),
@@ -129,8 +118,8 @@ export const OFFICIAL_TOOL_CONTRACTS = [
129
118
  })),
130
119
  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 })),
131
120
  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 })),
132
- 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)),
133
- 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)),
121
+ 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(analysisSearchInput)),
122
+ 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(analysisSearchInput)),
134
123
  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 })),
135
124
  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 })),
136
125
  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 })),
@@ -152,6 +141,8 @@ export const ENHANCED_TOOL_CONTRACTS = [
152
141
  enhanced("binary_overview", "Use immediately after opening a target to summarize document, exhaustive procedure/string counts, and a bounded segment sample. detail controls segment fields and limit controls only the returned segment sample.", enhancedInputSchemas.binary_overview),
153
142
  enhanced("analyze_function", "Preferred bounded analysis for one procedure symbol or address. Returns identity, provider-specific pseudocode, optional assembly, comments, calls, typed-or-explicitly-unavailable references, referenced strings/names, and local CFG blocks with exact truncation metadata.", enhancedInputSchemas.analyze_function),
154
143
  enhanced("trace_feature", "Trace a bounded literal feature query through matching strings and procedures, xrefs, and truthful containing-procedure resolution. Returns the operation budget, truncation, and residual unknowns; unknown_registry_approved: true records them durably without inferring reference kinds.", enhancedInputSchemas.trace_feature),
144
+ enhanced("find_code_for_string", "Resolve one literal string query to bounded analyzed string entries, xrefs, and truthful containing-procedure candidates. Returns an Evidence ID, exact operation budget, truncation, and residual unknowns; it never infers reference kinds or runtime reachability.", enhancedInputSchemas.find_code_for_string),
145
+ enhanced("trace_call_path", "Trace a deterministic bounded caller or callee path from one exact procedure address, optionally stopping at a goal. Returns visited nodes, direct-call edges, one shortest traversal path, failures, frontier, consumed limits, an Evidence ID, and explicit residual unknowns without claiming unresolved indirect calls are absent.", enhancedInputSchemas.trace_call_path),
155
146
  ];
156
147
  /** Session-owned Evidence bundle export options. */
157
148
  export const exportEvidenceBundleInputSchema = z.strictObject({
@@ -215,8 +206,9 @@ export const TOOL_CONTRACTS = [
215
206
  ...ARTIFACT_TOOL_CONTRACTS,
216
207
  ...MANAGED_TOOL_CONTRACTS,
217
208
  ...MANAGED_WORKFLOW_TOOL_CONTRACTS,
218
- ...BROWSER_TOOL_CONTRACTS,
209
+ ...BROWSER_PROVIDER_TOOL_CONTRACTS,
219
210
  ...ELECTRON_TOOL_CONTRACTS,
211
+ ...JAVASCRIPT_RUNTIME_OBSERVATION_TOOL_CONTRACTS,
220
212
  ...APPLICATION_TOOL_CONTRACTS,
221
213
  ...SESSION_TOOL_CONTRACTS,
222
214
  ];
@@ -38,6 +38,9 @@ export const TOOL_EFFECTS = {
38
38
  procedure_callees: evidence,
39
39
  procedure_callers: evidence,
40
40
  procedure_info: evidence,
41
+ read_function_instructions: evidence,
42
+ read_bytes: evidence,
43
+ address_to_file_offset: evidence,
41
44
  procedure_references: evidence,
42
45
  procedure_pseudo_code: evidence,
43
46
  resolve_containing_procedure: evidence,
@@ -65,12 +68,15 @@ export const TOOL_EFFECTS = {
65
68
  binary_overview: evidence,
66
69
  analyze_function: evidence,
67
70
  trace_feature: effects({ mutatesSession: true, idempotent: false }),
71
+ find_code_for_string: effects({ mutatesSession: true, idempotent: false }),
72
+ trace_call_path: effects({ mutatesSession: true, idempotent: false }),
68
73
  inspect_macho: nativeEvidence,
69
74
  inspect_signature: nativeEvidence,
70
75
  inspect_plist: nativeEvidence,
71
76
  list_architectures: nativeEvidence,
72
77
  demangle_swift: nativeEvidence,
73
78
  inventory_artifact: evidence,
79
+ inspect_artifact: evidence,
74
80
  extract_artifact: effects({ mutatesSession: true, writesFilesystem: true }),
75
81
  inspect_managed_artifact: evidence,
76
82
  inspect_managed_members: evidence,
@@ -88,14 +94,29 @@ export const TOOL_EFFECTS = {
88
94
  compare_web_captures: browserEvidence,
89
95
  capture_web_screenshot: browserEvidence,
90
96
  compare_web_screenshots: browserEvidence,
97
+ capture_browser_scenario: effects({
98
+ mutatesTarget: true,
99
+ mutatesSession: true,
100
+ writesFilesystem: true,
101
+ launchesProcess: true,
102
+ accessesNetwork: true,
103
+ changesUiState: true,
104
+ mayDiscardData: true,
105
+ idempotent: false,
106
+ }),
91
107
  list_electron_targets: browserEvidence,
92
108
  inspect_electron_page: browserEvidence,
109
+ list_javascript_runtime_targets: browserEvidence,
110
+ observe_javascript_runtime: browserEvidence,
93
111
  analyze_javascript_application: evidence,
94
112
  reconcile_javascript_runtime: evidence,
95
113
  trace_application_feature: evidence,
96
114
  trace_javascript_semantics: evidence,
97
115
  compare_application_versions: evidence,
116
+ compare_source_to_bundle: evidence,
98
117
  compare_javascript_export_shapes: evidence,
118
+ build_reconstruction_obligation_ledger: evidence,
119
+ evaluate_reconstruction_readiness: evidence,
99
120
  run_replay_machine: effects(),
100
121
  run_controlled_replay: effects({
101
122
  mutatesSession: true,