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
@@ -0,0 +1,266 @@
1
+ import { z } from "zod";
2
+ import { recordedNoteCoverageIssues } from "./recordedCrashNoteCoverage.js";
3
+ const hex = z.string().regex(/^0x(?:0|[1-9a-f][0-9a-f]{0,15})$/);
4
+ const index = z.number().int().nonnegative();
5
+ const signed32 = z.number().int().min(-2147483648).max(2147483647);
6
+ const base64 = z
7
+ .string()
8
+ .regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/][AQgw]==|[A-Za-z0-9+/]{2}[AEIMQUYcgkosw048]=)?$/);
9
+ const range = z.strictObject({ offset: hex, bytes: hex });
10
+ const diagnostics = z.strictObject({
11
+ stdout: z.string(),
12
+ stderr: z.string(),
13
+ truncated: z.boolean(),
14
+ });
15
+ // Exact b"CORE\0"; a lossy display label cannot establish the Linux note ABI.
16
+ const LINUX_CORE_OWNER_BASE64 = "Q09SRQA=";
17
+ /** Complete register identities in the supported Linux amd64 PRSTATUS ABI order. */
18
+ export const RECORDED_LINUX_AMD64_REGISTERS = [
19
+ "r15",
20
+ "r14",
21
+ "r13",
22
+ "r12",
23
+ "rbp",
24
+ "rbx",
25
+ "r11",
26
+ "r10",
27
+ "r9",
28
+ "r8",
29
+ "rax",
30
+ "rcx",
31
+ "rdx",
32
+ "rsi",
33
+ "rdi",
34
+ "orig_rax",
35
+ "rip",
36
+ "cs",
37
+ "eflags",
38
+ "rsp",
39
+ "ss",
40
+ "fs_base",
41
+ "gs_base",
42
+ "ds",
43
+ "es",
44
+ "fs",
45
+ "gs",
46
+ ];
47
+ const supportedRegisters = new Set(RECORDED_LINUX_AMD64_REGISTERS);
48
+ /** Select an explicit recording and optionally request debugger-derived mapping context. */
49
+ export const inspectRecordedCrashInputSchema = z.strictObject({
50
+ path: z
51
+ .string()
52
+ .min(1)
53
+ .describe("Absolute filesystem path to a supplied Linux ELF core"),
54
+ include_debugger_context: z
55
+ .boolean()
56
+ .default(false)
57
+ .describe("Add core-only mapping candidates through caller-supplied GDB/pwndbg"),
58
+ });
59
+ /** Debugger map candidates preserve reported flags; zero does not establish absent permissions. */
60
+ export const recordedCrashDebuggerSchema = z.discriminatedUnion("status", [
61
+ z.strictObject({ status: z.literal("not-requested") }),
62
+ z.strictObject({
63
+ status: z.literal("available"),
64
+ gdb_version: z.string().min(1),
65
+ pwndbg_version: z.string().min(1),
66
+ connection: z.literal("core"),
67
+ executable: z.null(),
68
+ historical_pid: signed32,
69
+ reported_limits: z.strictObject({
70
+ address_space_bytes: index,
71
+ cpu_seconds: index,
72
+ file_size_bytes: index,
73
+ }),
74
+ maps: z.array(z.strictObject({
75
+ start: hex,
76
+ end: hex,
77
+ offset: hex,
78
+ reported_flags: index,
79
+ permissions: z
80
+ .strictObject({
81
+ read: z.boolean(),
82
+ write: z.boolean(),
83
+ execute: z.boolean(),
84
+ })
85
+ .nullable(),
86
+ pathname_display: z.string(),
87
+ current_file_identity: z.literal("unknown"),
88
+ })),
89
+ confidence: z.literal("derived"),
90
+ completeness: z.literal("unknown"),
91
+ diagnostics,
92
+ }),
93
+ ]);
94
+ /** Portable recorded observations; registers and source coordinates remain lossless. */
95
+ const recordedCrashObjectSchema = z.strictObject({
96
+ artifact: z.strictObject({
97
+ path: z.string().min(1),
98
+ sha256: z.string().regex(/^[a-f0-9]{64}$/),
99
+ bytes: index,
100
+ }),
101
+ format: z.literal("elf-core"),
102
+ architecture: z.literal("x86_64-little-endian"),
103
+ target_execution: z.literal("not-performed"),
104
+ live_process_identity: z.literal("unknown"),
105
+ segments: z.array(z.strictObject({
106
+ index,
107
+ type: z.union([z.string(), index]),
108
+ header_location: range,
109
+ offset: hex,
110
+ file_size: hex,
111
+ memory_size: hex,
112
+ virtual_address: hex,
113
+ physical_address: hex,
114
+ alignment: hex,
115
+ flags: hex,
116
+ file_backing: z.enum(["file", "none"]),
117
+ })),
118
+ notes: z.array(z.strictObject({
119
+ index,
120
+ segment_index: index,
121
+ type: z.union([z.string(), index]),
122
+ location: range,
123
+ owner_location: range,
124
+ owner_bytes_base64: base64,
125
+ owner_display: z.string().nullable(),
126
+ descriptor_location: range,
127
+ descriptor_bytes_base64: base64,
128
+ })),
129
+ note_padding: z.array(z.strictObject({
130
+ segment_index: index,
131
+ location: range,
132
+ bytes_base64: base64,
133
+ })),
134
+ threads: z.array(z.strictObject({
135
+ note_index: index,
136
+ historical_pid: signed32,
137
+ recorded_current_signal: z.number().int().min(-32768).max(32767),
138
+ registers: z.array(z.strictObject({
139
+ name: z.string().min(1),
140
+ value: hex,
141
+ location: range,
142
+ })),
143
+ })),
144
+ signals: z.array(z.strictObject({
145
+ note_index: index,
146
+ number: signed32,
147
+ code: signed32,
148
+ errno: signed32,
149
+ fault_address: hex.nullable(),
150
+ fault_address_meaning: z.enum(["recorded-sigsegv-address", "unknown"]),
151
+ thread_association: z.literal("unknown"),
152
+ })),
153
+ debugger: recordedCrashDebuggerSchema,
154
+ note_interpretation_completeness: z.literal("unknown"),
155
+ decoder_diagnostics: diagnostics,
156
+ diagnostics,
157
+ limitations: z.array(z.string()),
158
+ });
159
+ /** Provider payload excludes identity and diagnostics bound by the owned snapshot boundary. */
160
+ export const recordedCrashPayloadSchema = recordedCrashObjectSchema.omit({
161
+ artifact: true,
162
+ diagnostics: true,
163
+ debugger: true,
164
+ decoder_diagnostics: true,
165
+ });
166
+ /** Validate the next consumer's file ranges, note links and register representations. */
167
+ export const recordedCrashSchema = recordedCrashObjectSchema.superRefine((value, context) => {
168
+ const fail = (message) => context.addIssue({ code: "custom", message });
169
+ const within = (item, start = 0n, end = BigInt(value.artifact.bytes)) => {
170
+ const offset = BigInt(item.offset);
171
+ const bytes = BigInt(item.bytes);
172
+ return offset >= start && offset <= end && bytes <= end - offset;
173
+ };
174
+ for (const issue of recordedNoteCoverageIssues(value.segments, value.notes, value.note_padding))
175
+ fail(issue);
176
+ for (const [position, segment] of value.segments.entries()) {
177
+ if (position !== segment.index || !within(segment.header_location))
178
+ fail("Invalid original segment identity or header range.");
179
+ if (segment.file_backing === "file" &&
180
+ !within({ offset: segment.offset, bytes: segment.file_size }))
181
+ fail("Recorded segment exceeds artifact bytes.");
182
+ if (segment.type === "PT_LOAD" &&
183
+ BigInt(segment.file_size) > BigInt(segment.memory_size))
184
+ fail("Recorded PT_LOAD file size exceeds memory size.");
185
+ }
186
+ for (const [position, note] of value.notes.entries()) {
187
+ const segment = value.segments[note.segment_index];
188
+ if (position !== note.index || segment?.type !== "PT_NOTE") {
189
+ fail("Invalid original note identity or segment reference.");
190
+ continue;
191
+ }
192
+ const decodedLength = (raw) => BigInt((raw.length / 4) * 3 -
193
+ (raw.endsWith("==") ? 2 : raw.endsWith("=") ? 1 : 0));
194
+ if (decodedLength(note.owner_bytes_base64) !==
195
+ BigInt(note.owner_location.bytes) ||
196
+ decodedLength(note.descriptor_bytes_base64) !==
197
+ BigInt(note.descriptor_location.bytes))
198
+ fail("Raw note lengths differ from their source ranges.");
199
+ const start = BigInt(segment.offset);
200
+ const end = start + BigInt(segment.file_size);
201
+ if (!within(note.location, start, end) ||
202
+ !within(note.owner_location, BigInt(note.location.offset), BigInt(note.location.offset) + BigInt(note.location.bytes)) ||
203
+ !within(note.descriptor_location, BigInt(note.location.offset), BigInt(note.location.offset) + BigInt(note.location.bytes)))
204
+ fail("Note source ranges exceed their recorded segment.");
205
+ }
206
+ for (const padding of value.note_padding) {
207
+ const segment = value.segments[padding.segment_index];
208
+ if (segment?.type !== "PT_NOTE" ||
209
+ !within(padding.location, BigInt(segment.offset), BigInt(segment.offset) + BigInt(segment.file_size)))
210
+ fail("Invalid recorded note padding range.");
211
+ }
212
+ for (const [kind, rows] of [
213
+ ["NT_PRSTATUS", value.threads],
214
+ ["NT_SIGINFO", value.signals],
215
+ ]) {
216
+ const matchingNotes = value.notes.filter((note) => note.type === kind &&
217
+ note.owner_bytes_base64 === LINUX_CORE_OWNER_BASE64);
218
+ if (rows.length !== matchingNotes.length ||
219
+ new Set(rows.map(({ note_index }) => note_index)).size !== rows.length)
220
+ fail("Each supported raw note requires exactly one corresponding interpretation.");
221
+ }
222
+ for (const thread of value.threads) {
223
+ const note = value.notes[thread.note_index];
224
+ if (note?.type !== "NT_PRSTATUS" ||
225
+ note.owner_display !== "CORE" ||
226
+ note.owner_bytes_base64 !== LINUX_CORE_OWNER_BASE64) {
227
+ fail("Thread references a different note kind.");
228
+ continue;
229
+ }
230
+ if (thread.registers.length !== RECORDED_LINUX_AMD64_REGISTERS.length ||
231
+ !thread.registers.every(({ name }) => supportedRegisters.has(name)) ||
232
+ new Set(thread.registers.map(({ name }) => name)).size !==
233
+ thread.registers.length)
234
+ fail("Each recorded thread requires every supported register exactly once.");
235
+ for (const register of thread.registers)
236
+ if (BigInt(register.location.bytes) !== 8n ||
237
+ !within(register.location, BigInt(note.descriptor_location.offset), BigInt(note.descriptor_location.offset) +
238
+ BigInt(note.descriptor_location.bytes)))
239
+ fail("Register source exceeds its descriptor.");
240
+ }
241
+ for (const signal of value.signals) {
242
+ if (value.notes[signal.note_index]?.type !== "NT_SIGINFO" ||
243
+ value.notes[signal.note_index]?.owner_display !== "CORE" ||
244
+ value.notes[signal.note_index]?.owner_bytes_base64 !==
245
+ LINUX_CORE_OWNER_BASE64)
246
+ fail("Signal references a different note kind.");
247
+ const known = signal.number === 11 && (signal.code === 1 || signal.code === 2);
248
+ if (known !== (signal.fault_address !== null) ||
249
+ (signal.fault_address !== null) !==
250
+ (signal.fault_address_meaning === "recorded-sigsegv-address"))
251
+ fail("Signal union meaning does not match recorded SIGSEGV code.");
252
+ }
253
+ if (value.debugger.status === "available")
254
+ for (const map of value.debugger.maps) {
255
+ if (BigInt(map.end) < BigInt(map.start))
256
+ fail("Debugger mapping end precedes its start.");
257
+ if (map.permissions !== null &&
258
+ (map.permissions.read !== Boolean(map.reported_flags & 4) ||
259
+ map.permissions.write !== Boolean(map.reported_flags & 2) ||
260
+ map.permissions.execute !== Boolean(map.reported_flags & 1)))
261
+ fail("Mapping permissions differ from reported flags.");
262
+ if ((map.reported_flags === 0 || map.reported_flags > 7) !==
263
+ (map.permissions === null))
264
+ fail("Unreported or unfamiliar map flags require unknown permissions.");
265
+ }
266
+ });
@@ -0,0 +1,73 @@
1
+ const align = (size) => ((size + 3n) / 4n) * 4n;
2
+ const layoutMatches = (note) => {
3
+ const start = BigInt(note.location.offset);
4
+ const owner = BigInt(note.owner_location.bytes);
5
+ const descriptor = BigInt(note.descriptor_location.bytes);
6
+ return (BigInt(note.owner_location.offset) === start + 12n &&
7
+ BigInt(note.descriptor_location.offset) === start + 12n + align(owner) &&
8
+ BigInt(note.location.bytes) === 12n + align(owner) + align(descriptor));
9
+ };
10
+ const paddingMatches = (item, segment) => {
11
+ const bytes = BigInt(item.location.bytes);
12
+ const decodedLength = (item.bytes_base64.length / 4) * 3 -
13
+ (item.bytes_base64.endsWith("==")
14
+ ? 2
15
+ : item.bytes_base64.endsWith("=")
16
+ ? 1
17
+ : 0);
18
+ return (bytes > 0n &&
19
+ bytes < 12n &&
20
+ BigInt(decodedLength) === bytes &&
21
+ /^A*={0,2}$/.test(item.bytes_base64) &&
22
+ segment !== undefined &&
23
+ BigInt(item.location.offset) + bytes ===
24
+ BigInt(segment.offset) + BigInt(segment.file_size));
25
+ };
26
+ /** Require exact aligned note layouts and one complete, nonoverlapping physical coverage. */
27
+ export function recordedNoteCoverageIssues(segments, notes, padding) {
28
+ const issues = [];
29
+ const bySegment = new Map();
30
+ const all = [];
31
+ const add = (segment, range) => {
32
+ const ranges = bySegment.get(segment) ?? [];
33
+ ranges.push(range);
34
+ bySegment.set(segment, ranges);
35
+ all.push(range);
36
+ };
37
+ for (const note of notes) {
38
+ if (!layoutMatches(note))
39
+ issues.push("Recorded note layout differs from its aligned header/owner/descriptor ranges.");
40
+ add(note.segment_index, note.location);
41
+ }
42
+ for (const item of padding) {
43
+ if (!paddingMatches(item, segments[item.segment_index]))
44
+ issues.push("Recorded note padding must be a short zero-filled segment tail.");
45
+ add(item.segment_index, item.location);
46
+ }
47
+ const compare = (left, right) => BigInt(left.offset) < BigInt(right.offset)
48
+ ? -1
49
+ : BigInt(left.offset) > BigInt(right.offset)
50
+ ? 1
51
+ : 0;
52
+ let end = 0n;
53
+ for (const range of all.sort(compare)) {
54
+ const start = BigInt(range.offset);
55
+ if (start < end)
56
+ issues.push("Physical recorded note/padding ranges overlap or repeat.");
57
+ if (start + BigInt(range.bytes) > end)
58
+ end = start + BigInt(range.bytes);
59
+ }
60
+ for (const segment of segments) {
61
+ if (segment.type !== "PT_NOTE")
62
+ continue;
63
+ let cursor = BigInt(segment.offset);
64
+ for (const range of (bySegment.get(segment.index) ?? []).sort(compare)) {
65
+ if (BigInt(range.offset) !== cursor)
66
+ issues.push("Recorded note/padding ranges leave a gap or overlap in their segment.");
67
+ cursor = BigInt(range.offset) + BigInt(range.bytes);
68
+ }
69
+ if (cursor !== BigInt(segment.offset) + BigInt(segment.file_size))
70
+ issues.push("Recorded note/padding ranges do not completely cover their segment.");
71
+ }
72
+ return issues;
73
+ }
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { jsonValueSchema } from "./jsonValue.js";
2
+ import { jsonValueSchema } from "../jsonValue.js";
3
3
  import { normalizationSchema } from "./processScenario.js";
4
4
  import { collectProcessCaptureIssues } from "./processCaptureValidation.js";
5
5
  export * from "./processScenario.js";
@@ -61,6 +61,18 @@ const fileEffectSchema = z.discriminatedUnion("status", [
61
61
  }),
62
62
  ]);
63
63
  /** Exact serialized shape of a process capture. */
64
+ const processSettlementSchema = z.discriminatedUnion("state", [
65
+ z.object({
66
+ state: z.literal("quiesced"),
67
+ elapsed_ms: z.number().int().nonnegative(),
68
+ cleanup_outcome: z.enum(["not_required", "failed"]),
69
+ }),
70
+ z.object({
71
+ state: z.enum(["alive_at_deadline", "unverifiable"]),
72
+ elapsed_ms: z.number().int().nonnegative(),
73
+ cleanup_outcome: z.enum(["cleaned", "failed"]),
74
+ }),
75
+ ]);
64
76
  const processCaptureShapeSchema = z.strictObject({
65
77
  manifest: z.strictObject({
66
78
  rea_version: z.string().min(1),
@@ -74,7 +86,22 @@ const processCaptureShapeSchema = z.strictObject({
74
86
  comparison_contract: z.record(z.string(), jsonValueSchema),
75
87
  full_scenario_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
76
88
  comparison_contract_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
77
- executable_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
89
+ selected_executable_sha256: z
90
+ .string()
91
+ .regex(/^[a-f0-9]{64}$/u)
92
+ .nullable(),
93
+ executable_sha256: z
94
+ .string()
95
+ .regex(/^[a-f0-9]{64}$/u)
96
+ .nullable(),
97
+ legacy_executable_sha256: z
98
+ .string()
99
+ .regex(/^[a-f0-9]{64}$/u)
100
+ .optional(),
101
+ executable_identity: z.strictObject({
102
+ state: z.enum(["path_metadata_unchanged", "unknown"]),
103
+ reason: z.string().nullable(),
104
+ }),
78
105
  normalization_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
79
106
  }),
80
107
  normalization: normalizationSchema,
@@ -164,9 +191,119 @@ const processCaptureShapeSchema = z.strictObject({
164
191
  temporary_root: z.literal("removed"),
165
192
  }),
166
193
  });
194
+ const processCleanupResourceSchema = z.strictObject({
195
+ state: z.enum(["cleaned", "failed", "unverified", "not_required"]),
196
+ reason: z.string().nullable(),
197
+ });
198
+ const partialObservationFieldSchema = (value) => z.discriminatedUnion("state", [
199
+ z.strictObject({ state: z.literal("available"), value }),
200
+ z.strictObject({ state: z.literal("unavailable"), reason: z.string() }),
201
+ ]);
202
+ const incompleteProcessCaptureObservationsSchema = z.strictObject({
203
+ target_pid: partialObservationFieldSchema(z.number().int().positive()),
204
+ frames: partialObservationFieldSchema(processCaptureShapeSchema.shape.frames),
205
+ rendered_frames: partialObservationFieldSchema(processCaptureShapeSchema.shape.rendered_frames),
206
+ interaction_events: partialObservationFieldSchema(processCaptureShapeSchema.shape.interaction_events),
207
+ exit: partialObservationFieldSchema(z.strictObject({
208
+ code: z.number().int().nullable(),
209
+ signal: z.number().int().nullable(),
210
+ reason: z.enum(["exited", "timeout", "idle_timeout", "cancelled"]),
211
+ })),
212
+ settlement: partialObservationFieldSchema(z.strictObject({
213
+ state: z.enum(["quiesced", "alive_at_deadline", "unverifiable"]),
214
+ elapsed_ms: z.number().int().nonnegative(),
215
+ })),
216
+ process_samples: partialObservationFieldSchema(processCaptureShapeSchema.shape.process_samples),
217
+ filesystem_snapshots: z.strictObject({
218
+ before: partialObservationFieldSchema(z.strictObject({
219
+ files: z.array(fileStateSchema),
220
+ truncated: z.boolean(),
221
+ })),
222
+ after: partialObservationFieldSchema(z.strictObject({
223
+ files: z.array(fileStateSchema),
224
+ truncated: z.boolean(),
225
+ })),
226
+ }),
227
+ event_journal: partialObservationFieldSchema(processCaptureShapeSchema.shape.event_journal),
228
+ manifest: partialObservationFieldSchema(processCaptureShapeSchema.shape.manifest),
229
+ });
230
+ const partialCleanupReportSchema = z.strictObject({
231
+ owned_process_group: processCleanupResourceSchema,
232
+ terminal_renderer: processCleanupResourceSchema,
233
+ temporary_root: processCleanupResourceSchema,
234
+ });
235
+ const partialObservationMetadataSchema = z.strictObject({
236
+ cleanup: partialCleanupReportSchema,
237
+ execution_failure: z.string().nullable(),
238
+ });
239
+ const completedCaptureObservationSchema = z.strictObject({
240
+ capture: processCaptureShapeSchema
241
+ .omit({ cleanup: true })
242
+ .extend({ settlement: processSettlementSchema }),
243
+ });
244
+ const incompleteCaptureObservationSchema = z.strictObject({
245
+ observations: incompleteProcessCaptureObservationsSchema,
246
+ });
247
+ /** Validated, non-comparable process observations attached to cleanup errors. */
248
+ export const partialProcessCaptureObservationSchema = z
249
+ .union([
250
+ completedCaptureObservationSchema.extend(partialObservationMetadataSchema.shape),
251
+ incompleteCaptureObservationSchema.extend(partialObservationMetadataSchema.shape),
252
+ ])
253
+ .superRefine((partial, context) => {
254
+ if (!Object.values(partial.cleanup).some(({ state }) => state === "failed" || state === "unverified"))
255
+ context.addIssue({
256
+ code: "custom",
257
+ path: ["cleanup"],
258
+ message: "partial observations require incomplete resource cleanup",
259
+ });
260
+ if ("observations" in partial) {
261
+ const { observations } = partial;
262
+ if (![
263
+ observations.frames,
264
+ observations.interaction_events,
265
+ observations.process_samples,
266
+ observations.filesystem_snapshots.before,
267
+ observations.event_journal,
268
+ ].some(({ state }) => state === "available"))
269
+ context.addIssue({
270
+ code: "custom",
271
+ path: ["observations"],
272
+ message: "incomplete observations contain no collected evidence",
273
+ });
274
+ return;
275
+ }
276
+ const { capture } = partial;
277
+ const settlement = capture.settlement.state === "quiesced"
278
+ ? {
279
+ ...capture.settlement,
280
+ cleanup_outcome: "not_required",
281
+ }
282
+ : { ...capture.settlement, cleanup_outcome: "cleaned" };
283
+ const validationCapture = {
284
+ ...capture,
285
+ settlement,
286
+ cleanup: {
287
+ owned_process_group: "verified",
288
+ temporary_root: "removed",
289
+ },
290
+ };
291
+ for (const issue of collectProcessCaptureIssues(validationCapture))
292
+ context.addIssue({
293
+ code: "custom",
294
+ path: ["capture", ...issue.path.split(".")],
295
+ message: issue.message,
296
+ });
297
+ });
167
298
  /** Exact serialized shape plus all process-capture semantic invariants. */
168
299
  export const processCaptureSchema = processCaptureShapeSchema
169
300
  .superRefine((capture, context) => {
301
+ if (capture.settlement.cleanup_outcome === "failed")
302
+ context.addIssue({
303
+ code: "custom",
304
+ path: ["settlement", "cleanup_outcome"],
305
+ message: "verified captures cannot contain failed cleanup",
306
+ });
170
307
  for (const issue of collectProcessCaptureIssues(capture))
171
308
  context.addIssue({
172
309
  code: "custom",
@@ -22,7 +22,12 @@ export const EMPTY_PROCESS_CAPTURE_EXAMPLE = {
22
22
  comparison_contract: comparisonContract,
23
23
  full_scenario_sha256: digestProcessCommitment(scenario),
24
24
  comparison_contract_sha256: digestProcessCommitment(comparisonContract),
25
+ selected_executable_sha256: "0".repeat(64),
25
26
  executable_sha256: "0".repeat(64),
27
+ executable_identity: {
28
+ state: "path_metadata_unchanged",
29
+ reason: null,
30
+ },
26
31
  normalization_sha256: digestProcessCommitment(normalization),
27
32
  },
28
33
  normalization,
@@ -0,0 +1,54 @@
1
+ import { processCaptureSchema, } from "./processCapture.js";
2
+ import { z } from "zod";
3
+ const verifiedCaptures = new WeakSet();
4
+ const isVerifiedCapture = (capture) => verifiedCaptures.has(capture);
5
+ const attachProof = (capture) => {
6
+ verifiedCaptures.add(capture);
7
+ if (isVerifiedCapture(capture))
8
+ return capture;
9
+ throw new TypeError("Process Capture proof ownership failed");
10
+ };
11
+ const recordSchema = z.record(z.string(), z.unknown());
12
+ const LEGACY_EXECUTABLE_IDENTITY_REASON = "Legacy v3 capture did not distinguish selected and launch executable digests";
13
+ const migrateLegacyV3Capture = (input) => {
14
+ const capture = recordSchema.safeParse(input);
15
+ if (!capture.success)
16
+ return input;
17
+ const manifest = recordSchema.safeParse(capture.data.manifest);
18
+ if (!manifest.success)
19
+ return input;
20
+ if (manifest.data.provider_version !== "3" ||
21
+ "selected_executable_sha256" in manifest.data ||
22
+ "executable_identity" in manifest.data ||
23
+ "legacy_executable_sha256" in manifest.data)
24
+ return input;
25
+ const { executable_sha256 } = manifest.data;
26
+ if (typeof executable_sha256 !== "string" ||
27
+ !/^[a-f0-9]{64}$/u.test(executable_sha256))
28
+ return input;
29
+ return {
30
+ ...capture.data,
31
+ manifest: {
32
+ ...manifest.data,
33
+ selected_executable_sha256: null,
34
+ executable_sha256: null,
35
+ executable_identity: {
36
+ state: "unknown",
37
+ reason: LEGACY_EXECUTABLE_IDENTITY_REASON,
38
+ },
39
+ legacy_executable_sha256: executable_sha256,
40
+ },
41
+ };
42
+ };
43
+ /** Parse unknown input and reject invalid commitments or semantics. */
44
+ export const parseProcessCapture = (input) => {
45
+ const parsed = processCaptureSchema.safeParse(migrateLegacyV3Capture(input));
46
+ if (parsed.success)
47
+ return attachProof(parsed.data);
48
+ const issues = parsed.error.issues.flatMap((issue) => issue.code === "custom"
49
+ ? [{ path: issue.path.join("."), message: issue.message }]
50
+ : []);
51
+ if (issues.length > 0)
52
+ throw new TypeError(`Invalid process capture: ${issues.map(({ path, message }) => `${path}: ${message}`).join("; ")}`);
53
+ throw parsed.error;
54
+ };
@@ -5,8 +5,24 @@ const orderedTimestamps = (values) => values.every((value, index) => {
5
5
  });
6
6
  const validateCommitments = (capture, require) => {
7
7
  const { manifest } = capture;
8
- require(manifest.scenario.executable_sha256 ===
9
- manifest.executable_sha256, "manifest.executable_sha256", "executable commitment does not match the scenario projection");
8
+ if (manifest.legacy_executable_sha256 !== undefined) {
9
+ require(manifest.selected_executable_sha256 === null &&
10
+ manifest.executable_sha256 === null &&
11
+ manifest.executable_identity.state === "unknown" &&
12
+ manifest.executable_identity.reason !== null &&
13
+ manifest.scenario.executable_sha256 ===
14
+ manifest.legacy_executable_sha256, "manifest.legacy_executable_sha256", "legacy executable digest must remain distinct from unknown selected and launch digests");
15
+ }
16
+ else {
17
+ require(manifest.scenario.executable_sha256 ===
18
+ manifest.selected_executable_sha256, "manifest.selected_executable_sha256", "selected executable commitment does not match the scenario projection");
19
+ }
20
+ require(manifest.executable_identity.state === "path_metadata_unchanged"
21
+ ? manifest.executable_sha256 === manifest.selected_executable_sha256 &&
22
+ manifest.executable_identity.reason === null
23
+ : manifest.executable_sha256 === null &&
24
+ manifest.executable_identity.reason !==
25
+ null, "manifest.executable_identity", "launch identity and executable digest do not agree");
10
26
  for (const [field, value] of [
11
27
  ["full_scenario_sha256", manifest.scenario],
12
28
  ["comparison_contract_sha256", manifest.comparison_contract],
@@ -1,6 +1,6 @@
1
1
  import canonicalize from "canonicalize";
2
2
  import { z } from "zod";
3
- import { jsonValueSchema } from "./jsonValue.js";
3
+ import { jsonValueSchema } from "../jsonValue.js";
4
4
  import { compareProcessTraces, processTraceOutcomesDiffer, processTraceComparisonResultSchema, } from "./processTraceComparison.js";
5
5
  import { dimensionsForTraceSources, traceCoversObservedDimension, } from "./processTraceDimensionProjection.js";
6
6
  /** Comparison classification that never equates incomplete evidence. */
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { jsonValueSchema } from "./jsonValue.js";
2
+ import { jsonValueSchema } from "../jsonValue.js";
3
3
  /** Process-capture observation families shared by live drivers and trace assertions. */
4
4
  export const processObservationSourceSchema = z.enum([
5
5
  "terminal_raw",
@@ -1,6 +1,6 @@
1
1
  import canonicalize from "canonicalize";
2
2
  import { z } from "zod";
3
- import { jsonValueSchema } from "./jsonValue.js";
3
+ import { jsonValueSchema } from "../jsonValue.js";
4
4
  import { comparableProcessObservationPayload, processObservationSourceSchema, } from "./processObservation.js";
5
5
  const identifierSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._-]*$/u);
6
6
  /** Process observation families admitted by a declared trace specification. */
@@ -1,4 +1,4 @@
1
- import { AnalysisError } from "./analysisErrorBase.js";
1
+ import { AnalysisError, } from "./analysisErrorBase.js";
2
2
  /** No configured provider can satisfy a requested operation or target binding. */
3
3
  export class ProviderSelectionError extends AnalysisError {
4
4
  _tag = "ProviderSelectionError";
@@ -10,7 +10,9 @@ export class ProviderSelectionError extends AnalysisError {
10
10
  userMessage;
11
11
  constructor(options) {
12
12
  const operation = options.operation ?? "open_binary";
13
- super(providerSelectionDiagnostic(options));
13
+ super(providerSelectionDiagnostic(options), options.capturedOutput === undefined
14
+ ? undefined
15
+ : { capturedOutput: options.capturedOutput });
14
16
  this.operation = operation;
15
17
  this.reason = options.reason;
16
18
  this.requestedProviderId = options.requestedProviderId;
@@ -7,9 +7,9 @@ import { uniqueSorted } from "./canonicalOrdering.js";
7
7
  import { parseEvidence } from "./evidence.js";
8
8
  import { parseEvidenceBundle } from "./evidenceBundle.js";
9
9
  import { functionComparisonResultSchema } from "./functionComparison.js";
10
- import { PROCESS_PROVIDER, isProcessEvidenceProvider, } from "./processEvidenceProvider.js";
10
+ import { PROCESS_PROVIDER, isProcessEvidenceProvider, } from "./process/processEvidenceProvider.js";
11
11
  import { functionDossierSchema } from "./hopperValues.js";
12
- import { deriveProcessComparisonStatus, PROCESS_COMPARISON_DIMENSIONS, processCaptureComparisonSchema, processCaptureSchema, } from "./processCapture.js";
12
+ import { deriveProcessComparisonStatus, PROCESS_COMPARISON_DIMENSIONS, processCaptureComparisonSchema, parseProcessCapture, } from "./process/processCapture.js";
13
13
  import { reconstructionClaimResultSchema, reconstructionSpecificationSchema, reconstructionVerificationResultSchema, } from "./reconstructionVerificationSchemas.js";
14
14
  import { reconstructionClaimUnknowns, reconstructionProbes, reconstructionUnknownHeads, } from "./reconstructionUnknowns.js";
15
15
  const evidenceIdSchema = prefixedDigestSchema("ev");
@@ -125,7 +125,7 @@ const validateSourceKinds = (claim, sources) => {
125
125
  throw new TypeError("Comparison source Evidence has an unexpected observation type");
126
126
  for (const source of sources) {
127
127
  if (claim.kind === "behavioral")
128
- processCaptureSchema.parse(source.normalized_result);
128
+ parseProcessCapture(source.normalized_result);
129
129
  else if (claim.kind === "structural-function")
130
130
  functionDossierSchema.parse(source.normalized_result);
131
131
  else