rea-agents 5.0.0 → 6.0.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 (275) hide show
  1. package/README.md +157 -650
  2. package/bridge/mitmproxy/capture.py +210 -0
  3. package/bridge/native/rea_lldb_tracer.py +303 -0
  4. package/bridge/process/ProcessRunTokenReader.swift +263 -0
  5. package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
  6. package/bridge/pwndbg/core_context.py +101 -0
  7. package/bridge/pwndbg/launch.py +39 -0
  8. package/bridge/pwndbg/launch_impl.py +34 -0
  9. package/bridge/pwntools/decoder_runtime.py +59 -0
  10. package/bridge/pwntools/layout.py +39 -0
  11. package/bridge/pwntools/layout_impl.py +309 -0
  12. package/bridge/pwntools/recorded_crash.py +39 -0
  13. package/bridge/pwntools/recorded_crash_impl.py +143 -0
  14. package/dist/android/JadxProvider.js +1 -0
  15. package/dist/application/CapabilityInventory.js +21 -0
  16. package/dist/application/DirectAnalysis.js +97 -23
  17. package/dist/application/EvidenceBundleFiles.js +1 -1
  18. package/dist/application/ReconstructionObligationCandidates.js +5 -1
  19. package/dist/application/WebNetworkCapturePort.js +1 -0
  20. package/dist/application/WebNetworkCaptureService.js +132 -0
  21. package/dist/application/WindowsCapabilities.js +1 -1
  22. package/dist/application/binary/AnalysisSnapshotCache.js +49 -6
  23. package/dist/application/binary/BinarySession.js +38 -10
  24. package/dist/application/binary/BinarySessionOpen.js +16 -3
  25. package/dist/application/binary/BinarySessionRecords.js +20 -0
  26. package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
  27. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +57 -0
  28. package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
  29. package/dist/application/binaryDiagnostics/RecordedCrashService.js +60 -0
  30. package/dist/application/evm/EvmInterfacePort.js +1 -0
  31. package/dist/application/evm/EvmInterfaceService.js +62 -0
  32. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -2
  33. package/dist/application/javascript/JavaScriptApplicationService.js +15 -2
  34. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +42 -23
  35. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
  36. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +74 -24
  37. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +23 -10
  38. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
  39. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +145 -70
  40. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
  41. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
  42. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
  43. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
  44. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
  45. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
  46. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
  47. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +5 -5
  48. package/dist/application/{ProcessCli.js → process/ProcessCli.js} +10 -10
  49. package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +4 -4
  50. package/dist/artifacts/ArtifactProvider.js +30 -3
  51. package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
  52. package/dist/artifacts/ZipArtifactReader.js +3 -0
  53. package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
  54. package/dist/artifacts/apple/MachoLoadCommandReader.js +294 -0
  55. package/dist/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
  56. package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +3 -3
  57. package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
  58. package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
  59. package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
  60. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +3 -3
  61. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
  62. package/dist/artifacts/readStableArtifact.js +20 -4
  63. package/dist/browser/CdpCaptureEventHandlers.js +90 -2
  64. package/dist/browser/CdpCaptureEvents.js +9 -0
  65. package/dist/browser/PlaywrightElectronActiveProvider.js +12 -3
  66. package/dist/browser/history/CaptureFailures.js +101 -0
  67. package/dist/browser/history/CaptureFormatError.js +10 -0
  68. package/dist/browser/history/CaptureRedaction.js +65 -0
  69. package/dist/browser/history/CaptureRelease.js +12 -0
  70. package/dist/browser/history/HarCapture.js +165 -0
  71. package/dist/browser/history/HarCaptureAdapter.js +20 -0
  72. package/dist/browser/history/HarCaptureProcess.js +57 -0
  73. package/dist/browser/history/HarJson.js +91 -0
  74. package/dist/browser/history/HarSchema.js +72 -0
  75. package/dist/browser/history/HistoricalCaptureDecoder.js +186 -0
  76. package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
  77. package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
  78. package/dist/cli/artifactCommands.js +26 -1
  79. package/dist/cli/binaryDiagnosticsCommands.js +39 -0
  80. package/dist/cli/coreAnalysisCommands.js +2 -2
  81. package/dist/cli/coreBinaryCommands.js +8 -8
  82. package/dist/cli/electronCommands.js +16 -9
  83. package/dist/cli/evmCommands.js +24 -0
  84. package/dist/cli/firmwareCommands.js +6 -3
  85. package/dist/cli/javascriptApplicationAnalysis.js +16 -3
  86. package/dist/cli/jsonOutput.js +133 -0
  87. package/dist/cli/nativeCallCommands.js +35 -0
  88. package/dist/cli/processCommands.js +1 -1
  89. package/dist/cli/streamedJsonOutput.js +56 -0
  90. package/dist/cli/utilityCommands.js +2 -0
  91. package/dist/cli/webNetworkCaptureCommands.js +40 -0
  92. package/dist/cli.js +9 -3
  93. package/dist/cliBrowserScenarioCommands.js +2 -2
  94. package/dist/cliCommandNames.js +6 -0
  95. package/dist/cliJsonInput.js +30 -1
  96. package/dist/cliOutput.js +21 -6
  97. package/dist/composition/binaryDiagnostics.js +8 -0
  98. package/dist/composition/evm.js +4 -0
  99. package/dist/composition/webNetworkCaptures.js +6 -0
  100. package/dist/contracts/artifactToolContracts.js +6 -0
  101. package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
  102. package/dist/contracts/browserToolContracts.js +4 -3
  103. package/dist/contracts/errorSchemas.js +8 -1
  104. package/dist/contracts/evm/evmToolContracts.js +20 -0
  105. package/dist/contracts/investigationExamples.js +2 -2
  106. package/dist/contracts/managed/managedToolContracts.js +7 -3
  107. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
  108. package/dist/contracts/native/nativeToolContracts.js +17 -1
  109. package/dist/contracts/officialToolContracts.js +12 -9
  110. package/dist/contracts/process/processCaptureExample.js +2 -0
  111. package/dist/contracts/sessionLifecycleInputs.js +22 -5
  112. package/dist/contracts/sessionStatusContract.js +10 -2
  113. package/dist/contracts/sessionToolContracts.js +8 -1
  114. package/dist/contracts/sessionToolSchemas.js +10 -3
  115. package/dist/contracts/toolContractExamples.js +1 -1
  116. package/dist/contracts/toolContracts.js +6 -0
  117. package/dist/contracts/toolEffects.js +30 -0
  118. package/dist/contracts/toolOutputSchemaGroups.js +5 -1
  119. package/dist/contracts/toolOutputSchemaPrimitives.js +1 -1
  120. package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
  121. package/dist/domain/analysisErrorBase.js +15 -0
  122. package/dist/domain/analysisErrorCore.js +59 -5
  123. package/dist/domain/analysisErrorPresentation.js +29 -1
  124. package/dist/domain/analysisErrorProjection.js +52 -2
  125. package/dist/domain/analysisSnapshot.js +166 -2
  126. package/dist/domain/apple/dyldPaths.js +81 -0
  127. package/dist/domain/apple/dylibResolution.js +367 -0
  128. package/dist/domain/apple/dylibResolutionFindings.js +75 -0
  129. package/dist/domain/artifactPathSyntax.js +1 -1
  130. package/dist/domain/browserObservation.js +1 -1
  131. package/dist/domain/browserObservationSchemas.js +13 -0
  132. package/dist/domain/browserScenarioValues.js +9 -2
  133. package/dist/domain/callPathSchemas.js +1 -1
  134. package/dist/domain/canonicalDigest.js +13 -1
  135. package/dist/domain/changedBehavior.js +3 -3
  136. package/dist/domain/comparisonStatus.js +2 -30
  137. package/dist/domain/conformanceTrustGate.js +0 -16
  138. package/dist/domain/evidence.js +17 -5
  139. package/dist/domain/evm/evmInterface.js +63 -0
  140. package/dist/domain/explicitSensitiveFailure.js +92 -0
  141. package/dist/domain/explicitSensitiveValues.js +10 -0
  142. package/dist/domain/firmware/firmwareAnalysis.js +8 -1
  143. package/dist/domain/javascript/electronActiveObservation.js +9 -4
  144. package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
  145. package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
  146. package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
  147. package/dist/domain/javascript/javascriptSemanticGraph.js +21 -5
  148. package/dist/domain/jsonValue.js +4 -0
  149. package/dist/domain/localPath.js +2 -0
  150. package/dist/domain/native/binaryLayout.js +357 -0
  151. package/dist/domain/native/nativeCallObservation.js +164 -0
  152. package/dist/domain/native/objcSwiftMetadata.js +0 -39
  153. package/dist/domain/native/recordedCrash.js +266 -0
  154. package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
  155. package/dist/domain/{processCapture.js → process/processCapture.js} +139 -2
  156. package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
  157. package/dist/domain/process/processCaptureParsing.js +54 -0
  158. package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
  159. package/dist/domain/{processComparison.js → process/processComparison.js} +1 -1
  160. package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
  161. package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
  162. package/dist/domain/providerSelectionError.js +4 -2
  163. package/dist/domain/reconstructionVerification.js +3 -3
  164. package/dist/domain/reconstructionVerificationSchemas.js +1 -1
  165. package/dist/domain/residualUnknown.js +3 -2
  166. package/dist/domain/staticRuntimeCorrelation.js +3 -3
  167. package/dist/domain/webCaptureDiff.js +1 -0
  168. package/dist/domain/webNetworkCapture.js +118 -0
  169. package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
  170. package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
  171. package/dist/dotnet/ManagedMemberInspector.js +4 -2
  172. package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
  173. package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
  174. package/dist/dotnet/ManagedMemberRows.js +14 -3
  175. package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
  176. package/dist/dotnet/ManagedMetadataInventory.js +38 -28
  177. package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
  178. package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
  179. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
  180. package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
  181. package/dist/dotnet/ManagedPeReader.js +11 -0
  182. package/dist/evm/EvmBytecodeCarrier.js +21 -0
  183. package/dist/evm/EvmWorkerLimits.js +40 -0
  184. package/dist/evm/EvmoleFailures.js +126 -0
  185. package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
  186. package/dist/evm/EvmoleInterfaceProvider.js +273 -0
  187. package/dist/evm/EvmoleInterfaceWorker.js +87 -0
  188. package/dist/evm/EvmoleRelease.js +16 -0
  189. package/dist/firmware/FirmwareCommand.js +1 -0
  190. package/dist/generatedPackageMetadata.js +2 -2
  191. package/dist/ghidra/GhidraLauncher.js +1 -0
  192. package/dist/ghidra/GhidraProvider.js +2 -2
  193. package/dist/ghidra/GhidraProviderCapabilities.js +1 -1
  194. package/dist/hopper/BridgeLauncher.js +2 -0
  195. package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
  196. package/dist/javascript/recovery/WakaruCommand.js +3 -0
  197. package/dist/javascript/sourceMaps/SourceMapCommand.js +1 -0
  198. package/dist/native/CommandRunner.js +2 -1
  199. package/dist/native/LldbCallTracer.js +278 -0
  200. package/dist/native/NativeCallObservation.js +135 -0
  201. package/dist/native/NativeMacOSProvider.js +19 -3
  202. package/dist/native/NativeMacOSProviderMetadata.js +8 -3
  203. package/dist/native/pwndbg/PwndbgCoreContext.js +160 -0
  204. package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
  205. package/dist/native/pwntools/PwntoolsFailures.js +180 -0
  206. package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
  207. package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
  208. package/dist/native/pwntools/PwntoolsRelease.js +19 -0
  209. package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
  210. package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
  211. package/dist/native/pwntools/RecordedCrashStructureBindings.js +101 -0
  212. package/dist/process/DarwinProcessRunTokenReader.js +294 -0
  213. package/dist/process/OwnedCommand.js +113 -0
  214. package/dist/process/ProcessOwnership.js +263 -33
  215. package/dist/process/ProcessOwnershipObservation.js +161 -24
  216. package/dist/process/ProviderProcess.js +30 -3
  217. package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
  218. package/dist/{application → process/capture}/ProcessCaptureError.js +17 -1
  219. package/dist/process/capture/ProcessCaptureLifecycle.js +615 -0
  220. package/dist/{application → process/capture}/ProcessHarness.js +195 -29
  221. package/dist/{application → process/capture}/ProcessSampling.js +2 -2
  222. package/dist/server/createServer.js +22 -0
  223. package/dist/server/promptCompletion.js +10 -3
  224. package/dist/server/registerBinaryDiagnosticsTools.js +17 -0
  225. package/dist/server/registerEvidenceTools.js +1 -1
  226. package/dist/server/registerEvmTools.js +17 -0
  227. package/dist/server/registerProcessComparisonTool.js +1 -1
  228. package/dist/server/registerRecordedCrashTools.js +17 -0
  229. package/dist/server/registerSessionTools.js +2 -2
  230. package/dist/server/registerWebNetworkCaptureTool.js +28 -0
  231. package/dist/server/sessionAvailabilityPolicy.js +3 -0
  232. package/dist/server/sessionToolPolicies.js +1 -1
  233. package/dist/server/toolResult.js +1 -1
  234. package/native/windows/build/manifest.json +2 -2
  235. package/native/windows/build/rea-windows-x64.node +0 -0
  236. package/package.json +37 -9
  237. package/scripts/rea.mjs +11 -3
  238. package/skills/reverse-engineer-anything/SKILL.md +23 -3
  239. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
  240. package/third_party/README.md +60 -0
  241. package/third_party/evmole/LICENSE +21 -0
  242. package/third_party/evmole/README.md +22 -0
  243. package/third_party/pwndbg/LICENSE.md +21 -0
  244. package/third_party/pwndbg/README.md +23 -0
  245. package/third_party/pwntools/README.md +40 -0
  246. package/dist/application/AuthorizedArtifactInventory.js +0 -7
  247. package/dist/application/ProcessCaptureLifecycle.js +0 -299
  248. package/dist/application/StoreFileLock.js +0 -124
  249. package/dist/contracts/processCaptureExample.js +0 -2
  250. package/dist/domain/bytecodeProvider.js +0 -178
  251. package/dist/domain/customProtocolCapture.js +0 -137
  252. package/dist/domain/eventProcessTree.js +0 -225
  253. package/dist/domain/mobileApplicationInvestigation.js +0 -159
  254. package/dist/domain/packageAnalysis.js +0 -123
  255. package/dist/domain/peInspection.js +0 -197
  256. package/dist/domain/processCaptureParsing.js +0 -21
  257. package/dist/domain/protocolCapture.js +0 -217
  258. package/dist/domain/runtimeIdentification.js +0 -212
  259. package/dist/generatedMcpToolCatalog.js +0 -37
  260. /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
  261. /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
  262. /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
  263. /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
  264. /package/dist/domain/{processScenario.js → process/processScenario.js} +0 -0
  265. /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
  266. /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
  267. /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
  268. /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
  269. /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
  270. /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
  271. /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
  272. /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
  273. /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
  274. /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
  275. /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
@@ -1,5 +1,6 @@
1
+ import { jsonValueSchema } from "./jsonValue.js";
1
2
  import { analysisErrorCategory, analysisErrorRemediationAction, analysisErrorUserMessage, assertKnownAnalysisErrorTag, } from "./analysisErrorPresentation.js";
2
- import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisOutputError, AnalysisTimeoutError, } from "./analysisErrorCore.js";
3
+ import { AnalysisAccessDeniedError, AnalysisArtifactChangedError, AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisUnsupportedTargetError, AnalysisInputError, AnalysisOutputError, AnalysisTimeoutError, AnalysisResourceConstraintError, } from "./analysisErrorCore.js";
3
4
  import { ArtifactOperationError } from "./artifactOperationError.js";
4
5
  import { BinaryTargetError } from "./configurationErrors.js";
5
6
  import { BrowserObservationError } from "./browserObservationError.js";
@@ -13,7 +14,10 @@ import {} from "./analysisErrorBase.js";
13
14
  export const projectAnalysisError = (error) => {
14
15
  assertKnownAnalysisErrorTag(error._tag);
15
16
  const code = errorCode(error);
16
- const details = errorDetails(error);
17
+ const primaryDetails = errorDetails(error);
18
+ const details = error.capturedOutput === undefined
19
+ ? primaryDetails
20
+ : { ...primaryDetails, captured_output: { ...error.capturedOutput } };
17
21
  return {
18
22
  code,
19
23
  category: analysisErrorCategory(error),
@@ -88,10 +92,14 @@ const STATIC_ERROR_CODES = {
88
92
  AnalysisOutputError: "unreadable_output",
89
93
  HopperProtocolError: "unreadable_output",
90
94
  AnalysisInputError: "invalid_request",
95
+ AnalysisAccessDeniedError: "access_denied",
96
+ AnalysisArtifactChangedError: "artifact_changed",
91
97
  AnalysisCapabilityUnavailableError: "capability_unavailable",
98
+ AnalysisUnsupportedTargetError: "unsupported_target",
92
99
  AnalysisCancelledError: "cancelled",
93
100
  HopperCancelledError: "cancelled",
94
101
  AnalysisTimeoutError: "provider_timeout",
102
+ AnalysisResourceConstraintError: "resource_constraint",
95
103
  HopperTimeoutError: "provider_timeout",
96
104
  HopperProcessError: "provider_unavailable",
97
105
  HopperStartError: "provider_unavailable",
@@ -120,6 +128,33 @@ const errorDetails = (error) => requestErrorDetails(error) ??
120
128
  providerErrorDetails(error) ??
121
129
  lifecycleErrorDetails(error);
122
130
  const requestErrorDetails = (error) => {
131
+ if (error instanceof AnalysisUnsupportedTargetError)
132
+ return {
133
+ operation: error.operation,
134
+ path: error.path,
135
+ reason: error.reason,
136
+ };
137
+ if (error instanceof AnalysisResourceConstraintError)
138
+ return {
139
+ operation: error.operation,
140
+ resource: error.resource,
141
+ reason: error.reason,
142
+ reported_limits: error.reportedLimits,
143
+ };
144
+ if (error instanceof AnalysisArtifactChangedError)
145
+ return {
146
+ operation: error.operation,
147
+ path: error.path,
148
+ reason: error.reason,
149
+ boundary: "stable-artifact-read",
150
+ };
151
+ if (error instanceof AnalysisAccessDeniedError)
152
+ return {
153
+ operation: error.operation,
154
+ path: error.path,
155
+ system_code: error.systemCode,
156
+ boundary: "filesystem-read",
157
+ };
123
158
  if (error instanceof AnalysisOutputError)
124
159
  return { operation: error.operation, reason: error.reason };
125
160
  if (error instanceof AnalysisInputError && error.issues.length > 0)
@@ -272,10 +307,24 @@ const lifecycleErrorDetails = (error) => {
272
307
  return {
273
308
  cleanup: "incomplete",
274
309
  resources: [...error.cleanupResources],
310
+ ...(error.cleanupReport === undefined
311
+ ? {}
312
+ : { cleanup_report: jsonValueSchema.parse(error.cleanupReport) }),
313
+ ...(error.executionFailure === undefined
314
+ ? {}
315
+ : { execution_failure: error.executionFailure }),
316
+ ...(error.partialObservation === undefined
317
+ ? {}
318
+ : {
319
+ partial_observation: jsonValueSchema.parse(error.partialObservation),
320
+ }),
275
321
  };
276
322
  if (error._tag === "ProcessCaptureError" &&
277
323
  error.userCategory === "cancelled")
278
324
  return { operation: "process_capture", cleanup: "complete" };
325
+ if (error._tag === "ProcessCaptureError" &&
326
+ error.executionFailure !== undefined)
327
+ return { execution_failure: error.executionFailure };
279
328
  if (error instanceof BinaryTargetError)
280
329
  return {
281
330
  path: error.path,
@@ -287,6 +336,7 @@ const lifecycleErrorDetails = (error) => {
287
336
  return undefined;
288
337
  };
289
338
  const RETRYABLE_CODES = new Set([
339
+ "artifact_changed",
290
340
  "invalid_request",
291
341
  "provider_timeout",
292
342
  "cancelled",
@@ -77,11 +77,26 @@ const entrySchema = z.object({
77
77
  subject: subjectSchema.nullable(),
78
78
  }),
79
79
  });
80
+ const workflowEntrySchema = z.object({
81
+ query_id: prefixedDigestSchema("query"),
82
+ operation: z.string().min(1),
83
+ parameters: jsonObjectSchema,
84
+ execution: z.object({
85
+ result: jsonValueSchema,
86
+ raw_result: jsonValueSchema.nullable(),
87
+ provider: committedProviderSchema,
88
+ analysis_profile: analysisProfileSchema,
89
+ limitations: z.array(z.string()),
90
+ locations: z.array(evidenceLocationSchema),
91
+ subject: subjectSchema.nullable(),
92
+ }),
93
+ });
80
94
  /** Provider- and profile-exact cache of successful immutable analysis calls. */
81
95
  export const analysisSnapshotSchema = z.object({
82
96
  target: targetSchema,
83
97
  binding: bindingSchema,
84
98
  entries: z.array(entrySchema),
99
+ workflow_entries: z.array(workflowEntrySchema).optional(),
85
100
  evidence_bundle: evidenceBundleSchema,
86
101
  });
87
102
  const canonicalJson = (value) => {
@@ -122,6 +137,11 @@ export const snapshotEvidenceForQuery = (snapshot, query) => {
122
137
  if (!snapshotMatchesBinding(snapshot, target, bindingProfile))
123
138
  return undefined;
124
139
  const encodedParameters = canonicalJson(parameters);
140
+ const queryId = analysisQueryId(snapshot.target, snapshot.binding, operation, parameters);
141
+ const entry = snapshot.entries.find((candidate) => candidate.query_id === queryId);
142
+ const workflowEntry = snapshot.workflow_entries?.find((candidate) => candidate.query_id === queryId);
143
+ if (entry === undefined && workflowEntry === undefined)
144
+ return undefined;
125
145
  return snapshot.evidence_bundle.records.find((record) => record.subject?.digest.sha256 === target.sha256 &&
126
146
  record.operation === operation &&
127
147
  record.provider.id === provider.id &&
@@ -129,8 +149,54 @@ export const snapshotEvidenceForQuery = (snapshot, query) => {
129
149
  record.provider.version === provider.version &&
130
150
  "analysis_profile" in record &&
131
151
  analysisProfilesEqual(record.analysis_profile, evidenceProfile) &&
132
- canonicalJson(record.parameters) === encodedParameters);
152
+ canonicalJson(record.parameters) === encodedParameters &&
153
+ ((entry !== undefined && evidenceMatchesEntry(record, entry, snapshot)) ||
154
+ (workflowEntry !== undefined &&
155
+ evidenceMatchesWorkflowEntry(record, workflowEntry, snapshot))));
156
+ };
157
+ /** Create one exact replay record for a derived application workflow result. */
158
+ export const createAnalysisSnapshotWorkflowEntry = (input) => {
159
+ const { target, binding, operation, parameters, execution } = input;
160
+ if (execution.provider.id !== execution.analysisProfile.provider.id ||
161
+ execution.provider.name !== execution.analysisProfile.provider.name ||
162
+ execution.provider.version !== execution.analysisProfile.provider.version)
163
+ throw new TypeError("Workflow snapshot execution provider does not match its profile");
164
+ return {
165
+ query_id: analysisQueryId(target, binding, operation, parameters),
166
+ operation,
167
+ parameters: jsonObjectSchema.parse(parameters),
168
+ execution: {
169
+ result: execution.result,
170
+ raw_result: execution.rawResult,
171
+ provider: execution.analysisProfile.provider,
172
+ analysis_profile: execution.analysisProfile,
173
+ limitations: [...execution.limitations],
174
+ locations: [...execution.locations],
175
+ subject: execution.subject === null
176
+ ? null
177
+ : {
178
+ ...execution.subject,
179
+ architecture: execution.subject.architecture ?? null,
180
+ },
181
+ },
182
+ };
133
183
  };
184
+ const evidenceMatchesEntry = (evidence, entry, snapshot) => isCorrespondingEvidence(evidence, snapshot) &&
185
+ canonicalJson({
186
+ query: evidenceQueryKey(evidence),
187
+ normalized_result: evidence.normalized_result,
188
+ raw_result: evidence.raw_result,
189
+ limitations: evidence.limitations,
190
+ locations: evidence.locations,
191
+ subject: evidence.subject === null
192
+ ? null
193
+ : {
194
+ local_path: evidence.subject.local_path,
195
+ sha256: evidence.subject.digest.sha256,
196
+ format: evidence.subject.format,
197
+ architecture: evidence.subject.architecture,
198
+ },
199
+ }) === entryEvidenceKey(entry, snapshot.binding);
134
200
  /** Compute the stable lookup key for one provider/profile-specific query. */
135
201
  export const analysisQueryId = (target, binding, operation, parameters) => `query_${createHash("sha256")
136
202
  .update(canonicalJson({ target, binding, operation, parameters }))
@@ -171,7 +237,9 @@ export const parseAnalysisSnapshot = (input) => {
171
237
  throw new TypeError("Analysis snapshot evidence contains records for another target");
172
238
  const ids = new Set();
173
239
  const boundEntries = [];
240
+ const boundWorkflowEntries = [];
174
241
  const index = createEvidenceIndex(parsed);
242
+ const workflowIndex = createWorkflowEvidenceIndex(parsed);
175
243
  for (const entry of parsed.entries) {
176
244
  if (entry.execution.provider.id !== parsed.binding.provider.id ||
177
245
  entry.execution.provider.name !== parsed.binding.provider.name ||
@@ -192,10 +260,41 @@ export const parseAnalysisSnapshot = (input) => {
192
260
  }
193
261
  boundEntries.push(entry);
194
262
  }
263
+ for (const entry of parsed.workflow_entries ?? []) {
264
+ if (entry.execution.provider.id !==
265
+ entry.execution.analysis_profile.provider.id ||
266
+ entry.execution.provider.name !==
267
+ entry.execution.analysis_profile.provider.name ||
268
+ entry.execution.provider.version !==
269
+ entry.execution.analysis_profile.provider.version)
270
+ throw new TypeError("Analysis snapshot workflow entry provider does not match its profile");
271
+ const expected = analysisQueryId(parsed.target, parsed.binding, entry.operation, entry.parameters);
272
+ if (entry.query_id !== expected)
273
+ throw new TypeError("Analysis snapshot workflow query identifier does not match");
274
+ if (ids.has(entry.query_id))
275
+ throw new TypeError("Analysis snapshot contains duplicate queries");
276
+ ids.add(entry.query_id);
277
+ if (!workflowEntryHasMatchingEvidence(entry, workflowIndex)) {
278
+ if (workflowEntryHasCorrespondingEvidence(entry, workflowIndex))
279
+ throw new TypeError(`Analysis snapshot workflow entry ${entry.operation} differs from its Evidence record`);
280
+ continue;
281
+ }
282
+ boundWorkflowEntries.push(entry);
283
+ }
195
284
  const sorted = [...parsed.entries].sort((left, right) => left.query_id.localeCompare(right.query_id));
196
285
  if (JSON.stringify(parsed.entries) !== JSON.stringify(sorted))
197
286
  throw new TypeError("Analysis snapshot entries are not canonical");
198
- return { ...parsed, entries: boundEntries };
287
+ const sortedWorkflows = [...(parsed.workflow_entries ?? [])].sort((left, right) => left.query_id.localeCompare(right.query_id));
288
+ if (parsed.workflow_entries !== undefined &&
289
+ JSON.stringify(parsed.workflow_entries) !== JSON.stringify(sortedWorkflows))
290
+ throw new TypeError("Analysis snapshot workflow entries are not canonical");
291
+ return {
292
+ ...parsed,
293
+ entries: boundEntries,
294
+ ...(parsed.workflow_entries === undefined
295
+ ? {}
296
+ : { workflow_entries: boundWorkflowEntries }),
297
+ };
199
298
  };
200
299
  const createEvidenceIndex = (snapshot) => {
201
300
  const matching = new Set();
@@ -259,5 +358,70 @@ const entryEvidenceKey = (entry, binding) => canonicalJson({
259
358
  architecture: entry.execution.subject.architecture,
260
359
  },
261
360
  });
361
+ const workflowEntryQueryKey = (entry) => canonicalJson({
362
+ operation: entry.operation,
363
+ parameters: entry.parameters,
364
+ provider: entry.execution.provider,
365
+ analysis_profile: entry.execution.analysis_profile,
366
+ });
367
+ const workflowEntryEvidenceKey = (entry) => canonicalJson({
368
+ query: workflowEntryQueryKey(entry),
369
+ normalized_result: entry.execution.result,
370
+ raw_result: entry.execution.raw_result,
371
+ limitations: entry.execution.limitations,
372
+ locations: entry.execution.locations,
373
+ subject: entry.execution.subject === null
374
+ ? null
375
+ : {
376
+ local_path: entry.execution.subject.path,
377
+ sha256: entry.execution.subject.sha256,
378
+ format: entry.execution.subject.format,
379
+ architecture: entry.execution.subject.architecture,
380
+ },
381
+ });
382
+ const isWorkflowEvidence = (evidence, snapshot, entry) => evidence.predicate_type === "rea.analysis" &&
383
+ evidence.confidence === "derived" &&
384
+ evidence.authority === "shipped-artifact" &&
385
+ evidence.subject?.digest.sha256 === snapshot.target.sha256 &&
386
+ "analysis_profile" in evidence &&
387
+ analysisProfilesEqual(evidence.analysis_profile, entry.execution.analysis_profile) &&
388
+ evidence.provider.id === entry.execution.provider.id &&
389
+ evidence.provider.name === entry.execution.provider.name &&
390
+ evidence.provider.version === entry.execution.provider.version;
391
+ const createWorkflowEvidenceIndex = (snapshot) => {
392
+ const matching = new Set();
393
+ const corresponding = new Set();
394
+ for (const evidence of snapshot.evidence_bundle.records) {
395
+ if (evidence.predicate_type !== "rea.analysis" ||
396
+ evidence.confidence !== "derived" ||
397
+ evidence.authority !== "shipped-artifact" ||
398
+ evidence.subject?.digest.sha256 !== snapshot.target.sha256 ||
399
+ !("analysis_profile" in evidence))
400
+ continue;
401
+ corresponding.add(evidenceQueryKey(evidence));
402
+ matching.add(canonicalJson(evidenceContentProjection(evidence)));
403
+ }
404
+ return { matching, corresponding };
405
+ };
406
+ const workflowEntryHasMatchingEvidence = (entry, index) => index.matching.has(workflowEntryEvidenceKey(entry));
407
+ const workflowEntryHasCorrespondingEvidence = (entry, index) => index.corresponding.has(workflowEntryQueryKey(entry));
408
+ const evidenceMatchesWorkflowEntry = (evidence, entry, snapshot) => isWorkflowEvidence(evidence, snapshot, entry) &&
409
+ canonicalJson(evidenceContentProjection(evidence)) ===
410
+ workflowEntryEvidenceKey(entry);
411
+ const evidenceContentProjection = (evidence) => ({
412
+ query: evidenceQueryKey(evidence),
413
+ normalized_result: evidence.normalized_result,
414
+ raw_result: evidence.raw_result,
415
+ limitations: evidence.limitations,
416
+ locations: evidence.locations,
417
+ subject: evidence.subject === null
418
+ ? null
419
+ : {
420
+ local_path: evidence.subject.local_path,
421
+ sha256: evidence.subject.digest.sha256,
422
+ format: evidence.subject.format,
423
+ architecture: evidence.subject.architecture,
424
+ },
425
+ });
262
426
  /** Serialize a validated snapshot with byte-stable canonical entry ordering. */
263
427
  export const serializeAnalysisSnapshot = (snapshot) => `${canonicalJson(parseAnalysisSnapshot(snapshot))}\n`;
@@ -0,0 +1,81 @@
1
+ const MAX_SYMLINK_HOPS = 32;
2
+ /**
3
+ * Resolve a root-relative path one segment at a time, as `open` would:
4
+ * symlinks are followed inside the root, `..` applies to the real parent,
5
+ * and any escape above the root or through an absolute link stops.
6
+ */
7
+ export const resolveTreePath = async (view, input) => {
8
+ const pending = segmentsOf(input);
9
+ const resolved = [];
10
+ let last;
11
+ let hops = 0;
12
+ while (pending.length > 0) {
13
+ const segment = pending.shift() ?? "";
14
+ if (segment === "..") {
15
+ if (resolved.length === 0)
16
+ return { kind: "escapes" };
17
+ resolved.pop();
18
+ last = { kind: "directory" };
19
+ continue;
20
+ }
21
+ const path = [...resolved, segment].join("/");
22
+ const entry = await view.entry(path);
23
+ if (entry === undefined)
24
+ return { kind: "absent" };
25
+ if (entry.kind === "symlink") {
26
+ hops += 1;
27
+ if (hops > MAX_SYMLINK_HOPS)
28
+ return { kind: "absent" };
29
+ if (entry.target.startsWith("/"))
30
+ return { kind: "escapes" };
31
+ pending.unshift(...segmentsOf(entry.target));
32
+ continue;
33
+ }
34
+ if (entry.kind === "file" && pending.length > 0)
35
+ return { kind: "absent" };
36
+ resolved.push(segment);
37
+ last = entry;
38
+ }
39
+ return last?.kind === "file"
40
+ ? { kind: "file", path: resolved.join("/") }
41
+ : { kind: "not-file" };
42
+ };
43
+ const segmentsOf = (path) => path.split("/").filter((segment) => segment !== "" && segment !== ".");
44
+ export const directoryOf = (path) => {
45
+ const index = path.lastIndexOf("/");
46
+ return index < 0 ? "" : path.slice(0, index);
47
+ };
48
+ export const joinPath = (directory, rest) => directory === "" ? rest : rest === "" ? directory : `${directory}/${rest}`;
49
+ /** Expand one dyld path prefix relative to its owning image. */
50
+ export const expandPrefix = (raw, context) => {
51
+ const variable = /^@(executable_path|loader_path)(?:\/(.*))?$/u.exec(raw);
52
+ if (variable !== null) {
53
+ const rest = variable[2] ?? "";
54
+ if (variable[1] === "loader_path")
55
+ return { scope: "target", path: joinPath(context.ownerDirectory, rest) };
56
+ return context.executable === null
57
+ ? { scope: "undetermined", path: raw }
58
+ : {
59
+ scope: "target",
60
+ path: joinPath(directoryOf(context.executable), rest),
61
+ };
62
+ }
63
+ if (raw.startsWith("/"))
64
+ return { scope: "outside", path: raw };
65
+ return { scope: "undetermined", path: raw };
66
+ };
67
+ /**
68
+ * Slices a process may load, best first, following dyld's graded
69
+ * architectures: an x86_64h process also accepts generic x86_64.
70
+ */
71
+ const COMPATIBLE_ARCHITECTURES = {
72
+ x86_64h: ["x86_64h", "x86_64"],
73
+ };
74
+ export const compatibleSlice = (slices, process) => {
75
+ for (const architecture of COMPATIBLE_ARCHITECTURES[process] ?? [process]) {
76
+ const slice = slices.find((item) => item.architecture === architecture);
77
+ if (slice !== undefined)
78
+ return slice;
79
+ }
80
+ return undefined;
81
+ };