rea-agents 6.2.0 → 6.3.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 (297) hide show
  1. package/README.md +18 -20
  2. package/bridge/hopper_bridge.py +2 -0
  3. package/dist/android/JadxProvider.js +8 -2
  4. package/dist/android/JadxSession.js +51 -9
  5. package/dist/application/BinaryTargetResolver.js +63 -17
  6. package/dist/application/BrowserScenarioEvidence.js +2 -2
  7. package/dist/application/ClientConfigurationDocument.js +28 -0
  8. package/dist/application/ClientRegistrationStatus.js +19 -6
  9. package/dist/application/DirectAnalysis.js +12 -6
  10. package/dist/application/DirectAnalysisCleanup.js +0 -1
  11. package/dist/application/DirectAnalysisStatus.js +2 -5
  12. package/dist/application/Doctor.js +25 -34
  13. package/dist/application/DoctorDiagnostics.js +1 -1
  14. package/dist/application/EvidenceBundleFiles.js +1 -1
  15. package/dist/application/InvestigationProviders.js +4 -4
  16. package/dist/application/JsonFiles.js +15 -15
  17. package/dist/application/LinuxHopper.js +2 -1
  18. package/dist/application/ReconstructionObligationCandidates.js +9 -2
  19. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  20. package/dist/application/RegularFileRead.js +17 -0
  21. package/dist/application/Setup.js +18 -7
  22. package/dist/application/SetupClientConfiguration.js +18 -7
  23. package/dist/application/SetupHost.js +6 -4
  24. package/dist/application/SetupPlan.js +19 -15
  25. package/dist/application/SetupSkill.js +57 -8
  26. package/dist/application/SupportedClients.js +43 -0
  27. package/dist/application/Uninstall.js +18 -2
  28. package/dist/application/UpdateMaintenance.js +6 -2
  29. package/dist/application/Utf8JsonInput.js +64 -0
  30. package/dist/application/WebScriptExportService.js +13 -6
  31. package/dist/application/android/AndroidAnalysisService.js +1 -1
  32. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  33. package/dist/application/binary/BinarySession.js +16 -0
  34. package/dist/application/binary/BinarySessionOpen.js +9 -1
  35. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  36. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  37. package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
  38. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  39. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  40. package/dist/application/javascript/JavaScriptApplicationService.js +1 -0
  41. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  42. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +0 -6
  43. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +8 -18
  44. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +34 -26
  45. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +44 -12
  46. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +6 -3
  47. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
  48. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  49. package/dist/application/javascript/JavaScriptModuleRelationships.js +5 -17
  50. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  51. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -2
  52. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
  53. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  54. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
  55. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +1 -1
  56. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  57. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  58. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +2 -2
  59. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +1 -1
  60. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  61. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  62. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +10 -7
  63. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  64. package/dist/application/native/NativeCallRoutes.js +2 -4
  65. package/dist/artifacts/ArtifactProvider.js +14 -16
  66. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  67. package/dist/artifacts/AsarArtifactReader.js +81 -17
  68. package/dist/artifacts/DirectoryArtifactReader.js +2 -2
  69. package/dist/artifacts/NativeDmgArtifactReader.js +152 -67
  70. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  71. package/dist/artifacts/apple/KeyedArchiveReader.js +54 -46
  72. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  73. package/dist/artifacts/extraction/ArtifactExtraction.js +29 -11
  74. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +7 -8
  75. package/dist/artifacts/inventory/classify.js +33 -14
  76. package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
  77. package/dist/artifacts/inventory/scanCanonical.js +28 -22
  78. package/dist/artifacts/inventory/scanReader.js +7 -11
  79. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
  80. package/dist/browser/CdpBrowserProvider.js +4 -3
  81. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  82. package/dist/browser/CdpElectronInspection.js +2 -2
  83. package/dist/browser/CdpElectronProvider.js +4 -3
  84. package/dist/browser/CdpElectronScripts.js +2 -2
  85. package/dist/browser/CdpWebMcpDiscovery.js +16 -13
  86. package/dist/browser/PlaywrightBrowserScenarioProvider.js +6 -6
  87. package/dist/browser/PlaywrightScenarioBrowser.js +145 -42
  88. package/dist/browser/PlaywrightScenarioSession.js +3 -11
  89. package/dist/browser/WebSourceMapFetcher.js +32 -6
  90. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  91. package/dist/cli/coreAnalysisCommands.js +2 -2
  92. package/dist/cli/coreBinaryCommands.js +13 -9
  93. package/dist/cli/electronCommands.js +9 -10
  94. package/dist/cli/javascriptApplicationAnalysis.js +2 -12
  95. package/dist/cli/jsonOutput.js +3 -2
  96. package/dist/cli/streamedJsonOutput.js +83 -4
  97. package/dist/cli/utilityCommands.js +2 -4
  98. package/dist/cli.js +5 -2
  99. package/dist/cliJsonFile.js +179 -0
  100. package/dist/cliJsonInput.js +47 -34
  101. package/dist/cliObservationOptions.js +4 -0
  102. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  103. package/dist/composition/browserScenario.js +2 -2
  104. package/dist/composition/directAnalysis.js +2 -3
  105. package/dist/contracts/artifactComparisonExample.js +5 -5
  106. package/dist/contracts/errorSchemas.js +3 -1
  107. package/dist/contracts/functionComparisonExample.js +8 -0
  108. package/dist/contracts/inputSchemaPresentation.js +94 -3
  109. package/dist/contracts/javascript/electronToolContracts.js +2 -1
  110. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  111. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  112. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  113. package/dist/contracts/managed/managedToolContracts.js +3 -2
  114. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  115. package/dist/contracts/native/nativeToolContracts.js +1 -1
  116. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  117. package/dist/contracts/sessionStatusContract.js +3 -2
  118. package/dist/contracts/sessionToolContracts.js +3 -2
  119. package/dist/contracts/sessionToolSchemas.js +3 -2
  120. package/dist/contracts/toolOutputSchemaGroups.js +2 -2
  121. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  122. package/dist/domain/analysisErrorBase.js +5 -0
  123. package/dist/domain/analysisErrorPresentation.js +4 -2
  124. package/dist/domain/analysisSnapshot.js +3 -1
  125. package/dist/domain/analysisView/analysisView.js +1 -3
  126. package/dist/domain/android/androidPartialObservation.js +36 -0
  127. package/dist/domain/apple/dylibResolution.js +1 -1
  128. package/dist/domain/artifactComparison.js +4 -4
  129. package/dist/domain/artifactGraph.js +1 -1
  130. package/dist/domain/artifactIdentity.js +8 -8
  131. package/dist/domain/artifactInspection.js +8 -8
  132. package/dist/domain/artifactInventoryEvidence.js +5 -5
  133. package/dist/domain/browserCompleteness.js +3 -2
  134. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  135. package/dist/domain/browserScenarioNormalization.js +3 -3
  136. package/dist/domain/browserScenarioValues.js +3 -2
  137. package/dist/domain/callPath.js +8 -10
  138. package/dist/domain/canonicalDigest.js +7 -1
  139. package/dist/domain/canonicalOrdering.js +1 -13
  140. package/dist/domain/changedBehavior.js +2 -3
  141. package/dist/domain/comparisonSemantics.js +0 -5
  142. package/dist/domain/digests.js +0 -3
  143. package/dist/domain/evidence.js +10 -5
  144. package/dist/domain/evidenceBundle.js +51 -33
  145. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  146. package/dist/domain/functionComparison.js +2 -1
  147. package/dist/domain/functionComparisonNormalization.js +4 -3
  148. package/dist/domain/functionComparisonResults.js +2 -2
  149. package/dist/domain/functionDossierEvidence.js +2 -1
  150. package/dist/domain/hopperValues.js +11 -15
  151. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  152. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +2 -2
  153. package/dist/domain/javascript/electronStaticAnalysisIpc.js +9 -1
  154. package/dist/domain/javascript/electronStaticAnalysisNative.js +5 -3
  155. package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
  156. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
  157. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
  158. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  159. package/dist/domain/javascript/javascriptApplicationGraph.js +15 -13
  160. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  161. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  162. package/dist/domain/javascript/javascriptApplicationVersionItems.js +45 -34
  163. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +7 -7
  164. package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
  165. package/dist/domain/javascript/javascriptAstValues.js +22 -0
  166. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  167. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  168. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  169. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  170. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  171. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  172. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  173. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  174. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -6
  175. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  176. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  177. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  178. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  179. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
  180. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  181. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  182. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  183. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  184. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  185. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  186. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -6
  187. package/dist/domain/javascript/javascriptSemanticAnalysis.js +200 -8
  188. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  189. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  190. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  191. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  192. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  193. package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
  194. package/dist/domain/javascript/javascriptSemanticGraph.js +142 -35
  195. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
  196. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  197. package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
  198. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +497 -113
  199. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  200. package/dist/domain/javascript/javascriptSemanticMutationValues.js +41 -27
  201. package/dist/domain/javascript/javascriptSemanticObjects.js +2 -6
  202. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  203. package/dist/domain/javascript/javascriptSemanticProjection.js +20 -14
  204. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  205. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
  206. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  207. package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
  208. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
  209. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  210. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  211. package/dist/domain/javascript/javascriptSemanticReturns.js +23 -27
  212. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
  213. package/dist/domain/javascript/javascriptSemanticValues.js +135 -24
  214. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  215. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  216. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
  217. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  218. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  219. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  220. package/dist/domain/jsonSerialization.js +109 -55
  221. package/dist/domain/jsonShape.js +46 -19
  222. package/dist/domain/localPath.js +10 -4
  223. package/dist/domain/managed/managedApplicationGraph.js +10 -6
  224. package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
  225. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  226. package/dist/domain/native/nativeCallObservation.js +2 -4
  227. package/dist/domain/native/nativeValueFlow.js +5 -11
  228. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  229. package/dist/domain/process/processCapture.js +11 -10
  230. package/dist/domain/process/processCaptureCoverage.js +8 -5
  231. package/dist/domain/process/processCaptureExample.js +43 -0
  232. package/dist/domain/process/processCaptureValidation.js +4 -3
  233. package/dist/domain/process/processComparison.js +0 -23
  234. package/dist/domain/process/processScenario.js +3 -3
  235. package/dist/domain/process/processTraceEvaluation.js +4 -4
  236. package/dist/domain/process/processTraceSpecification.js +1 -3
  237. package/dist/domain/providerCleanupError.js +6 -2
  238. package/dist/domain/reconstructionCoverage.js +2 -1
  239. package/dist/domain/reconstructionUnknowns.js +4 -3
  240. package/dist/domain/reconstructionVerification.js +3 -2
  241. package/dist/domain/referenceSourceGraph.js +7 -7
  242. package/dist/domain/referenceSourceImportParsing.js +34 -45
  243. package/dist/domain/residualUnknown.js +3 -2
  244. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  245. package/dist/domain/swiftSymbolClassification.js +6 -1
  246. package/dist/domain/symbolAnalysis.js +17 -2
  247. package/dist/domain/unicodeCodePointOrder.js +6 -0
  248. package/dist/domain/webBundleAnalyzerInspection.js +9 -1
  249. package/dist/domain/webCaptureDiff.js +71 -29
  250. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  251. package/dist/domain/webInventory.js +3 -2
  252. package/dist/domain/webMcpDiscovery.js +4 -3
  253. package/dist/domain/webScriptExport.js +1 -1
  254. package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
  255. package/dist/dotnet/ManagedStaticProvider.js +10 -7
  256. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  257. package/dist/filesystem/RegularFile.js +41 -0
  258. package/dist/generatedPackageMetadata.js +1 -1
  259. package/dist/ghidra/GhidraClient.js +14 -4
  260. package/dist/ghidra/GhidraInstallation.js +111 -10
  261. package/dist/ghidra/GhidraLauncher.js +43 -19
  262. package/dist/hopper/HopperCleanup.js +1 -1
  263. package/dist/ida/IdaOperationRunner.js +2 -0
  264. package/dist/ida/IdaSessionClient.js +4 -2
  265. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  266. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  267. package/dist/inspector/V8InspectorProvider.js +60 -8
  268. package/dist/main/shutdown.js +76 -32
  269. package/dist/main/transport.js +1 -1
  270. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  271. package/dist/native/AppleObjcProperties.js +17 -7
  272. package/dist/native/LldbCallTracer.js +241 -75
  273. package/dist/native/NativeMacOSProvider.js +10 -5
  274. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  275. package/dist/process/ProcessOwnershipObservation.js +9 -13
  276. package/dist/process/capture/FilesystemSnapshot.js +88 -18
  277. package/dist/process/capture/ProcessCaptureLifecycle.js +13 -27
  278. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  279. package/dist/process/capture/ProcessHarness.js +8 -21
  280. package/dist/server/analysisAdmission.js +8 -0
  281. package/dist/server/createServer.js +22 -23
  282. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -1
  283. package/dist/server/registerApplicationTools/helpers.js +3 -2
  284. package/dist/server/registerArtifactTools.js +2 -2
  285. package/dist/server/registerCloseLifecycleTool.js +6 -4
  286. package/dist/server/registerEnhancedTools.js +78 -73
  287. package/dist/server/registerEvidenceTools.js +54 -46
  288. package/dist/server/registerManagedTools.js +7 -4
  289. package/dist/server/registerOfficialTools.js +31 -25
  290. package/dist/server/registerSessionTools.js +9 -3
  291. package/native/windows/build/manifest.json +1 -1
  292. package/package.json +6 -3
  293. package/skills/reverse-engineer-anything/SKILL.md +5 -5
  294. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  295. package/dist/artifacts/inventory/policy.js +0 -2
  296. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  297. package/dist/server/registerNativeTools.js +0 -6
@@ -2,7 +2,6 @@ import { basename } from "node:path";
2
2
  import { createJavaScriptApplicationEdge, createJavaScriptApplicationNode, } from "../javascript/javascriptApplicationGraph.js";
3
3
  import { managedSourceCoverage } from "./managedApplicationGraphCoverage.js";
4
4
  import {} from "./managedArtifact.js";
5
- import { moduleCoverageState } from "./managedApplicationGraphNodeCoverage.js";
6
5
  /** Add the root managed artifact node to the graph state. */
7
6
  export const addArtifactNode = (state) => {
8
7
  const node = createJavaScriptApplicationNode({
@@ -19,7 +18,7 @@ export const addArtifactNode = (state) => {
19
18
  format: "pe",
20
19
  source: "managed-application-graph",
21
20
  },
22
- evidence: managedEvidence(state, "project-managed-artifact"),
21
+ evidence: projectedManagedEvidence(state, "project-managed-artifact"),
23
22
  },
24
23
  ],
25
24
  });
@@ -28,36 +27,36 @@ export const addArtifactNode = (state) => {
28
27
  };
29
28
  /** Add managed assembly and module identity nodes for the artifact. */
30
29
  export const addArtifactIdentityNodes = (state, artifactNode, parsed) => {
31
- const artifact = parsed.artifact?.result;
32
- const artifactCoverage = managedSourceCoverage(parsed.artifact?.result.coverage.state ?? "complete");
33
- if (artifact?.assembly !== undefined && artifact.assembly !== null) {
30
+ const artifactInput = parsed.artifact;
31
+ if (artifactInput !== null && artifactInput.result.assembly !== null) {
32
+ const assemblyFacts = artifactInput.result.assembly;
33
+ const artifactEvidence = sourceManagedEvidence(state, artifactInput.evidence, artifactInput.result.coverage.state);
34
34
  const assembly = createJavaScriptApplicationNode({
35
35
  kind: "managed-assembly",
36
- identity: artifactLocalIdentity(state.artifactSha256, "managed-assembly", artifact.assembly.token),
36
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-assembly", assemblyFacts.token),
37
37
  observations: [
38
38
  {
39
- label: artifact.assembly.name,
39
+ label: assemblyFacts.name,
40
40
  properties: {
41
- name: artifact.assembly.name,
42
- version: artifact.assembly.version,
43
- culture: artifact.assembly.culture,
44
- public_key_kind: artifact.assembly.public_key.kind,
41
+ name: assemblyFacts.name,
42
+ version: assemblyFacts.version,
43
+ culture: assemblyFacts.culture,
44
+ public_key_kind: assemblyFacts.public_key.kind,
45
45
  },
46
- evidence: managedEvidence(state, "inspect_managed_artifact", artifactCoverage),
46
+ evidence: artifactEvidence,
47
47
  },
48
48
  ],
49
49
  });
50
50
  state.nodes.push(assembly);
51
51
  addContainsEdge(state, artifactNode, assembly, {
52
52
  kind: "declares-managed-assembly",
53
- coverage: artifactCoverage,
53
+ coverage: artifactEvidence.coverage,
54
54
  });
55
55
  }
56
- const module = artifact?.module ??
57
- parsed.members?.result.module ??
58
- parsed.boundaries?.result.module;
59
- if (module !== undefined && module !== null) {
60
- const moduleCoverage = managedSourceCoverage(moduleCoverageState(parsed));
56
+ const moduleSource = selectModuleSource(parsed);
57
+ if (moduleSource !== null) {
58
+ const { module } = moduleSource;
59
+ const moduleEvidence = sourceManagedEvidence(state, moduleSource.evidence, moduleSource.coverageState);
61
60
  const moduleNode = createJavaScriptApplicationNode({
62
61
  kind: "managed-module",
63
62
  identity: artifactLocalIdentity(state.artifactSha256, "managed-module", module.mvid ?? module.token),
@@ -70,28 +69,51 @@ export const addArtifactIdentityNodes = (state, artifactNode, parsed) => {
70
69
  generation: module.generation,
71
70
  token: module.token,
72
71
  },
73
- evidence: managedEvidence(state, "inspect_managed_artifact", moduleCoverage),
72
+ evidence: moduleEvidence,
74
73
  },
75
74
  ],
76
75
  });
77
76
  state.nodes.push(moduleNode);
78
77
  addContainsEdge(state, artifactNode, moduleNode, {
79
78
  kind: "declares-managed-module",
80
- coverage: moduleCoverage,
79
+ coverage: moduleEvidence.coverage,
81
80
  });
82
81
  }
83
82
  };
83
+ const selectModuleSource = (parsed) => {
84
+ if (parsed.artifact?.result.module != null)
85
+ return {
86
+ module: parsed.artifact.result.module,
87
+ evidence: parsed.artifact.evidence,
88
+ coverageState: parsed.artifact.result.coverage.state,
89
+ };
90
+ if (parsed.members?.result.module != null)
91
+ return {
92
+ module: parsed.members.result.module,
93
+ evidence: parsed.members.evidence,
94
+ coverageState: parsed.members.result.coverage.state,
95
+ };
96
+ if (parsed.boundaries?.result.module != null)
97
+ return {
98
+ module: parsed.boundaries.result.module,
99
+ evidence: parsed.boundaries.evidence,
100
+ coverageState: parsed.boundaries.result.coverage.state,
101
+ };
102
+ return null;
103
+ };
84
104
  /** Add managed type, method, and field nodes from member evidence. */
85
105
  export const addMemberNodes = (state, artifactNode, parsed) => {
86
- const members = parsed.members?.result;
87
- if (members === undefined)
88
- return { types: 0, methods: 0, fields: 0 };
106
+ const memberInput = parsed.members;
107
+ if (memberInput === null)
108
+ return;
109
+ const members = memberInput.result;
89
110
  const { types, methods, fields } = members;
90
111
  const typeCoverage = managedSourceCoverage(members.coverage.state);
91
112
  const methodCoverage = managedSourceCoverage(members.coverage.state);
92
113
  const fieldCoverage = managedSourceCoverage(members.coverage.state);
114
+ const sourceEvidence = sourceManagedEvidence(state, memberInput.evidence, members.coverage.state);
93
115
  for (const type of types) {
94
- const node = typeNode(state, type, typeCoverage);
116
+ const node = typeNode(state, type, sourceEvidence);
95
117
  state.nodes.push(node);
96
118
  state.typeNodes.set(type.token, node);
97
119
  addContainsEdge(state, artifactNode, node, {
@@ -100,7 +122,7 @@ export const addMemberNodes = (state, artifactNode, parsed) => {
100
122
  });
101
123
  }
102
124
  for (const method of methods) {
103
- const node = methodNode(state, method, methodCoverage);
125
+ const node = methodNode(state, method, sourceEvidence);
104
126
  state.nodes.push(node);
105
127
  state.methodNodes.set(method.token, node);
106
128
  const owner = method.declaring_type_token === null
@@ -112,7 +134,7 @@ export const addMemberNodes = (state, artifactNode, parsed) => {
112
134
  });
113
135
  }
114
136
  for (const field of fields) {
115
- const node = fieldNode(state, field, fieldCoverage);
137
+ const node = fieldNode(state, field, sourceEvidence);
116
138
  state.nodes.push(node);
117
139
  state.fieldNodes.set(field.token, node);
118
140
  const owner = field.declaring_type_token === null
@@ -123,14 +145,9 @@ export const addMemberNodes = (state, artifactNode, parsed) => {
123
145
  coverage: fieldCoverage,
124
146
  });
125
147
  }
126
- return {
127
- types: types.length,
128
- methods: methods.length,
129
- fields: fields.length,
130
- };
131
148
  };
132
149
  /** Build a managed type application node. */
133
- const typeNode = (state, type, coverage) => createJavaScriptApplicationNode({
150
+ const typeNode = (state, type, evidence) => createJavaScriptApplicationNode({
134
151
  kind: "managed-type",
135
152
  identity: artifactLocalIdentity(state.artifactSha256, "managed-type-token", type.token),
136
153
  observations: [
@@ -144,12 +161,12 @@ const typeNode = (state, type, coverage) => createJavaScriptApplicationNode({
144
161
  flags: type.flags,
145
162
  extends_token: type.extends_token,
146
163
  },
147
- evidence: managedEvidence(state, "inspect_managed_members", coverage),
164
+ evidence,
148
165
  },
149
166
  ],
150
167
  });
151
168
  /** Build a managed method application node. */
152
- const methodNode = (state, method, coverage) => createJavaScriptApplicationNode({
169
+ const methodNode = (state, method, evidence) => createJavaScriptApplicationNode({
153
170
  kind: "managed-method",
154
171
  identity: artifactLocalIdentity(state.artifactSha256, "managed-method-token", method.token),
155
172
  observations: [
@@ -169,12 +186,12 @@ const methodNode = (state, method, coverage) => createJavaScriptApplicationNode(
169
186
  normalized_il_sha256: method.body.normalized_il_sha256,
170
187
  il_size: method.body.il_size,
171
188
  },
172
- evidence: managedEvidence(state, "inspect_managed_members", coverage),
189
+ evidence,
173
190
  },
174
191
  ],
175
192
  });
176
193
  /** Build a managed field application node. */
177
- const fieldNode = (state, field, coverage) => createJavaScriptApplicationNode({
194
+ const fieldNode = (state, field, evidence) => createJavaScriptApplicationNode({
178
195
  kind: "managed-field",
179
196
  identity: artifactLocalIdentity(state.artifactSha256, "managed-field-token", field.token),
180
197
  observations: [
@@ -191,24 +208,30 @@ const fieldNode = (state, field, coverage) => createJavaScriptApplicationNode({
191
208
  signature_sha256: field.signature.raw_sha256,
192
209
  signature_status: field.signature.parse_status,
193
210
  },
194
- evidence: managedEvidence(state, "inspect_managed_members", coverage),
211
+ evidence,
195
212
  },
196
213
  ],
197
214
  });
198
215
  /** Add P/Invoke import and native implementation boundary nodes. */
199
216
  export const addBoundaryNodes = (state, artifactNode, parsed) => {
200
- const boundaries = parsed.boundaries?.result;
201
- if (boundaries === undefined)
202
- return { pinvoke_imports: 0, native_implementations: 0 };
217
+ const boundaryInput = parsed.boundaries;
218
+ if (boundaryInput === null)
219
+ return;
220
+ const boundaries = boundaryInput.result;
203
221
  const { pinvoke_imports: pinvokes, native_implementations: implementations } = boundaries;
204
222
  const pinvokeCoverage = managedSourceCoverage(boundaries.coverage.state);
205
223
  const implementationCoverage = managedSourceCoverage(boundaries.coverage.state);
224
+ const sourceEvidence = sourceManagedEvidence(state, boundaryInput.evidence, boundaries.coverage.state);
206
225
  for (const pinvoke of pinvokes) {
207
- const node = pinvokeNode(state, pinvoke, pinvokeCoverage);
226
+ const node = pinvokeNode(state, pinvoke, sourceEvidence);
208
227
  state.nodes.push(node);
209
- const owner = pinvoke.member_token === null
210
- ? artifactNode
211
- : (state.methodNodes.get(pinvoke.member_token) ?? artifactNode);
228
+ const method = pinvoke.member_token === null
229
+ ? undefined
230
+ : state.methodNodes.get(pinvoke.member_token);
231
+ const memberEvidence = method === undefined || parsed.members === null
232
+ ? undefined
233
+ : parsed.members.evidence;
234
+ const owner = method ?? artifactNode;
212
235
  state.edges.push(createJavaScriptApplicationEdge({
213
236
  source_node_id: owner.node_id,
214
237
  target_node_id: node.node_id,
@@ -218,11 +241,11 @@ export const addBoundaryNodes = (state, artifactNode, parsed) => {
218
241
  import_name: pinvoke.import_name,
219
242
  import_scope_name: pinvoke.import_scope_name,
220
243
  },
221
- evidence: managedEvidence(state, "inspect_managed_native_boundaries", pinvokeCoverage),
244
+ evidence: pinvokeAssociationEvidence(state, boundaryInput.evidence, pinvokeCoverage, memberEvidence),
222
245
  }));
223
246
  }
224
247
  for (const implementation of implementations) {
225
- const node = nativeImplementationNode(state, implementation, implementationCoverage);
248
+ const node = nativeImplementationNode(state, implementation, sourceEvidence);
226
249
  state.nodes.push(node);
227
250
  const owner = state.methodNodes.get(implementation.token) ?? artifactNode;
228
251
  addContainsEdge(state, owner, node, {
@@ -230,13 +253,9 @@ export const addBoundaryNodes = (state, artifactNode, parsed) => {
230
253
  coverage: implementationCoverage,
231
254
  });
232
255
  }
233
- return {
234
- pinvoke_imports: pinvokes.length,
235
- native_implementations: implementations.length,
236
- };
237
256
  };
238
257
  /** Build a managed P/Invoke import application node. */
239
- const pinvokeNode = (state, pinvoke, coverage) => createJavaScriptApplicationNode({
258
+ const pinvokeNode = (state, pinvoke, evidence) => createJavaScriptApplicationNode({
240
259
  kind: "managed-pinvoke-import",
241
260
  identity: artifactLocalIdentity(state.artifactSha256, "managed-pinvoke-token", pinvoke.token),
242
261
  observations: [
@@ -252,12 +271,12 @@ const pinvokeNode = (state, pinvoke, coverage) => createJavaScriptApplicationNod
252
271
  call_convention: pinvoke.call_convention,
253
272
  verification: pinvoke.verification,
254
273
  },
255
- evidence: managedEvidence(state, "inspect_managed_native_boundaries", coverage),
274
+ evidence,
256
275
  },
257
276
  ],
258
277
  });
259
278
  /** Build a managed native implementation application node. */
260
- const nativeImplementationNode = (state, implementation, coverage) => createJavaScriptApplicationNode({
279
+ const nativeImplementationNode = (state, implementation, evidence) => createJavaScriptApplicationNode({
261
280
  kind: "managed-native-implementation",
262
281
  identity: artifactLocalIdentity(state.artifactSha256, "managed-native-implementation-token", implementation.token),
263
282
  observations: [
@@ -273,7 +292,7 @@ const nativeImplementationNode = (state, implementation, coverage) => createJava
273
292
  boundary_kind: implementation.boundary_kind,
274
293
  body_interpretation: implementation.body_interpretation,
275
294
  },
276
- evidence: managedEvidence(state, "inspect_managed_native_boundaries", coverage),
295
+ evidence,
277
296
  },
278
297
  ],
279
298
  });
@@ -284,7 +303,7 @@ const addContainsEdge = (state, source, target, options) => {
284
303
  target_node_id: target.node_id,
285
304
  relation: "contains",
286
305
  properties: { kind: options.kind },
287
- evidence: managedEvidence(state, "project-managed-contains", options.coverage),
306
+ evidence: projectedManagedEvidence(state, "project-managed-contains", options.coverage),
288
307
  }));
289
308
  };
290
309
  /** Build an artifact-local key identity for a managed graph entity. */
@@ -296,7 +315,13 @@ const artifactLocalIdentity = (artifactSha256, namespace, key) => ({
296
315
  key,
297
316
  });
298
317
  /** Build managed static-analysis evidence for a graph observation. */
299
- const managedEvidence = (state, operation, coverage = managedSourceCoverage("complete")) => ({
318
+ const sourceManagedEvidence = (state, source, coverageState) => createManagedEvidence(state, source.operation, managedSourceCoverage(coverageState), [source.evidence_id]);
319
+ const projectedManagedEvidence = (state, operation, coverage = managedSourceCoverage("complete")) => createManagedEvidence(state, operation, coverage, state.evidenceLinks);
320
+ const pinvokeAssociationEvidence = (state, boundaryEvidence, coverage, memberEvidence) => createManagedEvidence(state, boundaryEvidence.operation, coverage, [
321
+ boundaryEvidence.evidence_id,
322
+ ...(memberEvidence === undefined ? [] : [memberEvidence.evidence_id]),
323
+ ]);
324
+ const createManagedEvidence = (state, operation, coverage, evidenceIds) => ({
300
325
  authority: "managed-static-analysis",
301
326
  state: "observed",
302
327
  confidence: "exact",
@@ -324,7 +349,7 @@ const managedEvidence = (state, operation, coverage = managedSourceCoverage("com
324
349
  : [
325
350
  "The source managed Evidence slice is incomplete; unreturned or unavailable items remain unobserved.",
326
351
  ],
327
- evidence_ids: state.evidenceLinks,
352
+ evidence_ids: [...evidenceIds],
328
353
  });
329
354
  /** Sanitize an artifact path into a managed graph location. */
330
355
  const graphArtifactPath = (path) => {
@@ -11,21 +11,21 @@ export const sha256 = (value) => {
11
11
  const keyMethod = (item) => ({
12
12
  item,
13
13
  exactKey: item.body.status === "present" && item.body.normalized_il_sha256 !== null
14
- ? stableKey([
14
+ ? sha256([
15
15
  "method-exact",
16
16
  item.signature.raw_sha256,
17
17
  item.body.normalized_il_sha256,
18
18
  ])
19
19
  : null,
20
20
  // The raw blob is the exact signature; decoding only feeds shape keys.
21
- signatureKey: stableKey([
21
+ signatureKey: sha256([
22
22
  "method-signature",
23
23
  item.declaring_type,
24
24
  item.name,
25
25
  item.signature.raw_sha256,
26
26
  ]),
27
27
  structuralKey: item.signature.parse_status === "decoded" && item.body.status === "present"
28
- ? stableKey([
28
+ ? sha256([
29
29
  "method-structural",
30
30
  item.signature.kind,
31
31
  item.signature.calling_convention,
@@ -56,24 +56,23 @@ const keyMethod = (item) => ({
56
56
  const keyField = (item) => ({
57
57
  item,
58
58
  exactKey: item.signature.parse_status === "decoded"
59
- ? stableKey(["field-exact", item.signature.raw_sha256])
59
+ ? sha256(["field-exact", item.signature.raw_sha256])
60
60
  : null,
61
61
  // Only an undecoded field reaches this round: a decoded field with the
62
62
  // same raw signature already met its counterpart in the exact round.
63
- signatureKey: stableKey([
63
+ signatureKey: sha256([
64
64
  "field-signature",
65
65
  item.declaring_type,
66
66
  item.name,
67
67
  item.signature.raw_sha256,
68
68
  ]),
69
- structuralKey: stableKey([
69
+ structuralKey: sha256([
70
70
  "field-structural",
71
71
  item.signature.kind,
72
72
  item.signature.field_type,
73
73
  item.flags,
74
74
  ]),
75
75
  });
76
- const stableKey = (value) => sha256(value);
77
76
  const matchMethods = (left, right) => matchByKeys({
78
77
  left,
79
78
  right,
@@ -3,7 +3,7 @@ import { localPathStringSchema } from "../localPath.js";
3
3
  const hexSchema = z.string().regex(/^0x[0-9a-f]+$/u);
4
4
  const nativeString = z
5
5
  .string()
6
- .regex(/^[^\u0000]*$/u, "Native launch and breakpoint strings cannot contain NUL");
6
+ .regex(/^[^\x00]*$/u, "Native launch and breakpoint strings cannot contain NUL");
7
7
  /** Objective-C class names and selectors never contain spaces or brackets. */
8
8
  const objcName = nativeString
9
9
  .min(1)
@@ -46,9 +46,7 @@ export const nativeCallObservationInputSchema = z.strictObject({
46
46
  .record(z
47
47
  .string()
48
48
  .min(1)
49
- .regex(/^[^=\u0000]+$/u, "Environment names cannot contain '=' or NUL"), z
50
- .string()
51
- .regex(/^[^\u0000]*$/u, "Environment values cannot contain NUL"))
49
+ .regex(/^[^=\x00]+$/u, "Environment names cannot contain '=' or NUL"), z.string().regex(/^[^\x00]*$/u, "Environment values cannot contain NUL"))
52
50
  .default({})
53
51
  .describe("Overrides on top of the environment REA runs with."),
54
52
  working_directory: localPathStringSchema.optional(),
@@ -16,9 +16,7 @@ export const nativePcodeOperationSchema = z.strictObject({
16
16
  sequence: z.number().int().nonnegative(),
17
17
  opcode: z.string().min(1),
18
18
  is_dead: z.boolean(),
19
- block_membership: z
20
- .enum(["member", "detached", "unavailable"])
21
- .default("unavailable"),
19
+ block_membership: z.enum(["member", "detached", "unavailable"]),
22
20
  inputs: z.array(nativeVarnodeSchema),
23
21
  output: nativeVarnodeSchema.nullable(),
24
22
  });
@@ -50,20 +48,16 @@ export const nativeValueFlowSchema = z.discriminatedUnion("available", [
50
48
  operations: z.array(nativePcodeOperationSchema),
51
49
  def_use: z.array(nativePcodeDefUseSchema),
52
50
  effects: z.array(nativePcodeEffectSchema),
53
- parameters: z
54
- .array(z.strictObject({
51
+ parameters: z.array(z.strictObject({
55
52
  ordinal: z.number().int().nonnegative(),
56
53
  name: z.string(),
57
54
  data_type: z.string(),
58
- }))
59
- .default([]),
60
- parameter_uses: z
61
- .array(z.strictObject({
55
+ })),
56
+ parameter_uses: z.array(z.strictObject({
62
57
  ordinal: z.number().int().nonnegative(),
63
58
  use: z.string(),
64
59
  input_index: z.number().int().nonnegative(),
65
- }))
66
- .default([]),
60
+ })),
67
61
  truncated: z.boolean(),
68
62
  omitted_operations_lower_bound: z.number().int().nonnegative(),
69
63
  known_omitted_inputs: z.number().int().nonnegative(),
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { compareUnicodeCodePoints, compositeKey, } from "../unicodeCodePointOrder.js";
2
3
  /** Objective-C method type. */
3
4
  export const objcMethodTypeSchema = z.enum([
4
5
  "instance",
@@ -10,25 +11,22 @@ export const objcMethodTypeSchema = z.enum([
10
11
  export const objcPropertyAttributeSchema = z.strictObject({
11
12
  name: z.string().min(1),
12
13
  value: z.string(),
13
- is_weak: z.boolean().default(false),
14
- is_atomic: z.boolean().default(false),
15
- is_copy: z.boolean().default(false),
16
- is_strong: z.boolean().default(false),
17
14
  });
18
15
  /** Objective-C method metadata. */
19
16
  export const objcMethodSchema = z.strictObject({
20
17
  selector: z.string().min(1),
21
18
  method_type: objcMethodTypeSchema,
22
19
  address: z.number().int().nullable(),
23
- is_required: z.boolean().default(false),
24
- is_optional: z.boolean().default(false),
20
+ is_required: z.boolean().nullable(),
21
+ is_optional: z.boolean().nullable(),
25
22
  });
26
23
  /** Objective-C property metadata. */
27
24
  export const objcPropertySchema = z.strictObject({
28
25
  name: z.string().min(1),
29
26
  type_encoding: z.string().nullable(),
30
- attributes: z.array(objcPropertyAttributeSchema).default([]),
31
- is_readonly: z.boolean().default(false),
27
+ attributes: z.array(objcPropertyAttributeSchema),
28
+ atomicity: z.enum(["atomic", "nonatomic"]).nullable(),
29
+ is_readonly: z.boolean().nullable(),
32
30
  getter: z.string().nullable(),
33
31
  setter: z.string().nullable(),
34
32
  });
@@ -43,12 +41,12 @@ export const objcProtocolSchema = z.strictObject({
43
41
  export const objcClassSchema = z.strictObject({
44
42
  name: z.string().min(1),
45
43
  super_class: z.string().nullable(),
46
- is_meta_class: z.boolean().default(false),
47
- is_root_class: z.boolean().default(false),
44
+ is_meta_class: z.boolean().nullable(),
45
+ is_root_class: z.boolean().nullable(),
48
46
  methods: z.array(objcMethodSchema).default([]),
49
47
  properties: z.array(objcPropertySchema).default([]),
50
48
  protocols: z.array(z.string()).default([]),
51
- ivar_count: z.number().int().nonnegative().default(0),
49
+ ivar_count: z.number().int().nonnegative().nullable(),
52
50
  instance_size: z.number().int().nonnegative().nullable(),
53
51
  location: z
54
52
  .object({
@@ -333,23 +331,23 @@ export const inspectNativeDispatchMetadata = (names, maxRecords = 5_000) => {
333
331
  selector: implementation.selector,
334
332
  method_type: implementation.method_type,
335
333
  address: parseMetadataAddress(implementation.implementation_address),
336
- is_required: false,
337
- is_optional: false,
334
+ is_required: null,
335
+ is_optional: null,
338
336
  });
339
337
  methodsByClass.set(implementation.class_name, methods);
340
338
  }
341
339
  const classes = [...classNames].sort().map((name) => ({
342
340
  name,
343
341
  super_class: null,
344
- is_meta_class: false,
345
- is_root_class: false,
342
+ is_meta_class: null,
343
+ is_root_class: null,
346
344
  methods: methodsByClass.get(name) ?? [],
347
345
  properties: [],
348
346
  protocols: [],
349
- ivar_count: 0,
347
+ ivar_count: null,
350
348
  instance_size: null,
351
349
  }));
352
- const decodedImplementations = [...implementations.values()].sort((left, right) => `${left.class_name}:${left.selector}`.localeCompare(`${right.class_name}:${right.selector}`));
350
+ const decodedImplementations = [...implementations.values()].sort((left, right) => compareUnicodeCodePoints(compositeKey([left.class_name, left.selector]), compositeKey([right.class_name, right.selector])));
353
351
  const swift = swiftSymbols.length > 0;
354
352
  return objcSwiftMetadataSchema.parse({
355
353
  objc_classes: classes,
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { jsonValueSchema } from "../jsonValue.js";
3
3
  import { normalizationSchema } from "./processScenario.js";
4
4
  import { collectProcessCaptureIssues } from "./processCaptureValidation.js";
5
- import { processCaptureTruncationDetailsSchema, } from "./processCaptureCoverage.js";
5
+ import { filesystemCoverageSchema, processCaptureTruncationDetailsSchema, } from "./processCaptureCoverage.js";
6
6
  /** Capture collection whose members participate in global observation order. */
7
7
  export const PROCESS_CAPTURE_EVENT_COLLECTIONS = [
8
8
  "frames",
@@ -40,6 +40,13 @@ const fileStateSchema = z.discriminatedUnion("type", [
40
40
  symlink_target: z.null(),
41
41
  }),
42
42
  ]);
43
+ /** Canonical checkpoint facts retained even when capture completion fails. */
44
+ export const processFilesystemSnapshotSchema = z.strictObject({
45
+ files: z.array(fileStateSchema),
46
+ truncated: z.boolean(),
47
+ completeRoots: z.array(z.string()),
48
+ coverage: filesystemCoverageSchema,
49
+ });
43
50
  const fileEffectSchema = z.discriminatedUnion("status", [
44
51
  z.object({
45
52
  path: z.string(),
@@ -175,7 +182,7 @@ const processCaptureShapeSchema = z.strictObject({
175
182
  files_after: z.array(fileStateSchema),
176
183
  filesystem_effects: z.array(fileEffectSchema),
177
184
  truncated: z.boolean(),
178
- truncation_details: processCaptureTruncationDetailsSchema.optional(),
185
+ truncation_details: processCaptureTruncationDetailsSchema,
179
186
  limitations: z.array(z.string()),
180
187
  residual_unknowns: z.array(z.object({
181
188
  scope: z.enum([
@@ -221,14 +228,8 @@ const incompleteProcessCaptureObservationsSchema = z.strictObject({
221
228
  })),
222
229
  process_samples: partialObservationFieldSchema(processCaptureShapeSchema.shape.process_samples),
223
230
  filesystem_snapshots: z.strictObject({
224
- before: partialObservationFieldSchema(z.strictObject({
225
- files: z.array(fileStateSchema),
226
- truncated: z.boolean(),
227
- })),
228
- after: partialObservationFieldSchema(z.strictObject({
229
- files: z.array(fileStateSchema),
230
- truncated: z.boolean(),
231
- })),
231
+ before: partialObservationFieldSchema(processFilesystemSnapshotSchema),
232
+ after: partialObservationFieldSchema(processFilesystemSnapshotSchema),
232
233
  }),
233
234
  event_journal: partialObservationFieldSchema(processCaptureShapeSchema.shape.event_journal),
234
235
  manifest: partialObservationFieldSchema(processCaptureShapeSchema.shape.manifest),
@@ -18,7 +18,12 @@ export const filesystemCoverageSchema = z.strictObject({
18
18
  path: z.string(),
19
19
  size_bytes: z.number().int().nonnegative(),
20
20
  remaining_budget_bytes: z.number().int().nonnegative(),
21
- reason: z.enum(["file_bytes_budget", "file_changed_or_short_read"]),
21
+ reason: z.enum([
22
+ "file_bytes_budget",
23
+ "file_changed_or_short_read",
24
+ "file_unavailable",
25
+ ]),
26
+ system_code: z.string().nullable(),
22
27
  })),
23
28
  });
24
29
  /** Actual budget accounting; rendered bytes count state and visible lines, not JSON. */
@@ -39,17 +44,15 @@ export const processCaptureTruncationDetailsSchema = z.strictObject({
39
44
  });
40
45
  const omitted = (retention) => retention.observed_frames > retention.retained_frames;
41
46
  const filesystemTruncated = (coverage) => coverage.enumeration_truncated || coverage.hash_omissions.length > 0;
42
- /** Derive the legacy aggregate flag from independent producer observations. */
47
+ /** Derive the aggregate truncation flag from independent producer observations. */
43
48
  export const hasCaptureTruncation = (details) => omitted(details.raw_terminal) ||
44
49
  omitted(details.rendered_terminal) ||
45
50
  filesystemTruncated(details.filesystem_before) ||
46
51
  filesystemTruncated(details.filesystem_after) ||
47
52
  details.process.sampling_partial;
48
- /** Older truncated captures lack enough information to localize missing observations. */
53
+ /** Whether producer accounting reports a gap in the selected observation source. */
49
54
  export const processSourceTruncated = (capture, source) => {
50
55
  const details = capture.truncation_details;
51
- if (details === undefined)
52
- return capture.truncated;
53
56
  switch (source) {
54
57
  case "terminal_raw":
55
58
  return omitted(details.raw_terminal);
@@ -56,6 +56,49 @@ export const EMPTY_PROCESS_CAPTURE_EXAMPLE = {
56
56
  files_after: [],
57
57
  filesystem_effects: [],
58
58
  truncated: false,
59
+ truncation_details: {
60
+ raw_terminal: {
61
+ budget_bytes: 1_000_000,
62
+ observed_bytes: 0,
63
+ retained_bytes: 0,
64
+ observed_frames: 0,
65
+ retained_frames: 0,
66
+ },
67
+ rendered_terminal: {
68
+ budget_bytes: 1_000_000,
69
+ observed_bytes: 0,
70
+ retained_bytes: 0,
71
+ observed_frames: 0,
72
+ retained_frames: 0,
73
+ },
74
+ filesystem_before: {
75
+ files_limit: 10_000,
76
+ depth_limit: 16,
77
+ enumeration_truncated: false,
78
+ enumeration_reasons: [],
79
+ hash_budget_bytes: 10_000_000,
80
+ hashed_bytes: 0,
81
+ hash_omissions: [],
82
+ },
83
+ filesystem_after: {
84
+ files_limit: 10_000,
85
+ depth_limit: 16,
86
+ enumeration_truncated: false,
87
+ enumeration_reasons: [],
88
+ hash_budget_bytes: 10_000_000,
89
+ hashed_bytes: 0,
90
+ hash_omissions: [],
91
+ },
92
+ process: {
93
+ sample_limit: 1_000,
94
+ sampling_partial: false,
95
+ retained_samples: 0,
96
+ sample_limit_reached: false,
97
+ sampling_failures: 0,
98
+ first_sampling_failure: null,
99
+ coverage: "sampled",
100
+ },
101
+ },
59
102
  limitations: [],
60
103
  residual_unknowns: [],
61
104
  cleanup: {
@@ -76,8 +76,6 @@ const validateLifecycle = (capture, require) => {
76
76
  };
77
77
  const validateCoverage = (capture, require) => {
78
78
  const details = capture.truncation_details;
79
- if (details === undefined)
80
- return;
81
79
  require(details.process.retained_samples === capture.process_samples.length &&
82
80
  details.process.retained_samples <= details.process.sample_limit &&
83
81
  details.process.sampling_partial ===
@@ -134,7 +132,10 @@ const validateCoverage = (capture, require) => {
134
132
  new Set(coverage.hash_omissions.map(({ path }) => path)).size ===
135
133
  unhashedFiles.size &&
136
134
  coverage.hash_omissions.every((omission) => unhashedFiles.get(omission.path)?.size === omission.size_bytes &&
137
- omission.remaining_budget_bytes <= coverage.hash_budget_bytes), `truncation_details.${name}.hash_omissions`, "every retained regular file without a digest must have one matching omission reason");
135
+ omission.remaining_budget_bytes <= coverage.hash_budget_bytes &&
136
+ (omission.reason === "file_unavailable"
137
+ ? omission.system_code !== null
138
+ : omission.system_code === null)), `truncation_details.${name}.hash_omissions`, "every retained regular file without a digest must have one matching omission reason");
138
139
  require(coverage.hashed_bytes ===
139
140
  files
140
141
  .filter((file) => file.type === "file" && file.sha256 !== null)