rea-agents 1.7.0 → 2.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 (156) hide show
  1. package/README.md +38 -31
  2. package/dist/application/CapabilityInventory.js +18 -0
  3. package/dist/application/CrossVersionInvestigation.js +10 -6
  4. package/dist/application/Doctor.js +56 -6
  5. package/dist/application/ElectronBoundaryAnalysis.js +96 -0
  6. package/dist/application/ElectronBoundaryGraph.js +9 -0
  7. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  8. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  9. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  10. package/dist/application/ElectronBoundaryGraphWindows.js +199 -0
  11. package/dist/application/EnhancedTools.js +38 -13
  12. package/dist/application/InvestigationProviders.js +30 -0
  13. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  14. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  15. package/dist/application/JavaScriptApplicationService.js +74 -0
  16. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  17. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  18. package/dist/application/JavaScriptArtifactAnalysis.js +7 -1
  19. package/dist/application/JavaScriptArtifactGraphBuilder.js +59 -16
  20. package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
  21. package/dist/application/JavaScriptArtifactReconstruction.js +3 -0
  22. package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
  23. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  24. package/dist/application/JavaScriptReplayService.js +266 -0
  25. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  26. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  27. package/dist/application/ManagedApplicationGraphService.js +55 -0
  28. package/dist/application/ManagedMemberComparisonService.js +122 -0
  29. package/dist/application/ManagedNativeVerificationService.js +39 -0
  30. package/dist/application/ManagedReconstructionService.js +58 -0
  31. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  32. package/dist/application/PermissionAuthority.js +1 -1
  33. package/dist/application/ProcessSampling.js +15 -11
  34. package/dist/application/ProjectPermissionStore.js +1 -0
  35. package/dist/application/runtime.js +2 -0
  36. package/dist/browser/CdpCaptureEvents.js +49 -0
  37. package/dist/browser/CdpElectronInspection.js +106 -162
  38. package/dist/browser/CdpElectronProvider.js +5 -1
  39. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  40. package/dist/browser/CdpElectronScripts.js +94 -0
  41. package/dist/browser/CdpElectronWorkers.js +56 -0
  42. package/dist/browser/CdpPageCapture.js +8 -4
  43. package/dist/catalogIdentity.js +4 -1
  44. package/dist/cli.js +388 -0
  45. package/dist/cliApplicationCommands.js +62 -0
  46. package/dist/cliCommandNames.js +13 -0
  47. package/dist/cliElectronCommands.js +103 -1
  48. package/dist/cliJsonInput.js +54 -0
  49. package/dist/config.js +83 -0
  50. package/dist/contracts/applicationToolContracts.js +91 -0
  51. package/dist/contracts/artifactToolContracts.js +5 -9
  52. package/dist/contracts/browserToolContracts.js +14 -62
  53. package/dist/contracts/electronToolContracts.js +45 -19
  54. package/dist/contracts/errorSchemas.js +1 -0
  55. package/dist/contracts/investigationExamples.js +0 -6
  56. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  57. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  58. package/dist/contracts/managedToolContracts.js +153 -0
  59. package/dist/contracts/managedWorkflowExamples.js +346 -0
  60. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  61. package/dist/contracts/nativeToolContracts.js +2 -6
  62. package/dist/contracts/promptContracts.js +18 -2
  63. package/dist/contracts/toolContractExamples.js +10 -25
  64. package/dist/contracts/toolContracts.js +47 -45
  65. package/dist/contracts/toolEffects.js +160 -0
  66. package/dist/contracts/toolOutputSchemas.js +46 -31
  67. package/dist/doctorRuntime.js +42 -1
  68. package/dist/domain/artifactComparison.js +3 -4
  69. package/dist/domain/browserObservation.js +3 -0
  70. package/dist/domain/bundleComparison.js +4 -4
  71. package/dist/domain/electronObservation.js +13 -0
  72. package/dist/domain/electronStaticAnalysis.js +9 -0
  73. package/dist/domain/electronStaticAnalysisBrowser.js +194 -0
  74. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  75. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  76. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  77. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  78. package/dist/domain/errors.js +67 -1
  79. package/dist/domain/functionComparisonSchemas.js +3 -8
  80. package/dist/domain/inputIssueProjection.js +52 -0
  81. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  82. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  83. package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
  84. package/dist/domain/javascriptApplicationGraph.js +2 -1
  85. package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
  86. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  87. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  88. package/dist/domain/javascriptApplicationVersionItems.js +221 -0
  89. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  90. package/dist/domain/javascriptFeatureSeed.js +140 -0
  91. package/dist/domain/javascriptFeatureTrace.js +232 -0
  92. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  93. package/dist/domain/javascriptFeatureTraversal.js +88 -0
  94. package/dist/domain/javascriptNativeHandoff.js +85 -0
  95. package/dist/domain/javascriptReplay.js +361 -0
  96. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  97. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  98. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  99. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  100. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  101. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  102. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  103. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  104. package/dist/domain/javascriptRuntimeStaticCandidates.js +191 -0
  105. package/dist/domain/javascriptStaticAnalysis.js +31 -43
  106. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  107. package/dist/domain/javascriptStaticAnalysisHelpers.js +10 -0
  108. package/dist/domain/javascriptStaticAnalysisState.js +6 -0
  109. package/dist/domain/managedApplicationGraph.js +556 -0
  110. package/dist/domain/managedArtifact.js +444 -0
  111. package/dist/domain/managedMemberComparison.js +565 -0
  112. package/dist/domain/managedNativeVerification.js +408 -0
  113. package/dist/domain/managedReconstruction.js +183 -0
  114. package/dist/domain/managedRuntimeCorrelation.js +175 -0
  115. package/dist/domain/reconstructionVerificationSchemas.js +1 -3
  116. package/dist/dotnet/ManagedArtifactInspector.js +318 -0
  117. package/dist/dotnet/ManagedMemberInspector.js +887 -0
  118. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  119. package/dist/dotnet/ManagedMetadataInventory.js +368 -0
  120. package/dist/dotnet/ManagedMetadataLayout.js +322 -0
  121. package/dist/dotnet/ManagedNativeBoundaryInspector.js +391 -0
  122. package/dist/dotnet/ManagedPeReader.js +157 -0
  123. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  124. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  125. package/dist/generatedPackageMetadata.js +2 -2
  126. package/dist/ghidra/GhidraProvider.js +6 -0
  127. package/dist/main.js +14 -0
  128. package/dist/replay/JavaScriptReplayWorker.js +286 -0
  129. package/dist/replay/LinuxJavaScriptReplayRunner.js +434 -0
  130. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  131. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  132. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  133. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  134. package/dist/server/createServer.js +52 -0
  135. package/dist/server/registerApplicationTools.js +115 -0
  136. package/dist/server/registerArtifactComparisonTool.js +16 -9
  137. package/dist/server/registerBrowserTools.js +33 -8
  138. package/dist/server/registerBundleComparisonTool.js +17 -20
  139. package/dist/server/registerElectronTools.js +45 -3
  140. package/dist/server/registerEnhancedTools.js +58 -13
  141. package/dist/server/registerEvidenceTools.js +5 -1
  142. package/dist/server/registerFunctionComparisonTool.js +14 -7
  143. package/dist/server/registerInvestigationTools.js +21 -17
  144. package/dist/server/registerManagedTools.js +6 -0
  145. package/dist/server/registerManagedWorkflowTools.js +277 -0
  146. package/dist/server/registerOfficialTools.js +8 -8
  147. package/dist/server/registerProcessComparisonTool.js +25 -47
  148. package/dist/server/registerSessionStatusTool.js +7 -7
  149. package/dist/server/registerSessionTools.js +51 -86
  150. package/dist/server/sessionEvidence.js +14 -19
  151. package/dist/server/toolInputValidation.js +77 -0
  152. package/dist/server/toolRegistrationOptions.js +79 -2
  153. package/dist/server/toolResult.js +25 -17
  154. package/package.json +12 -4
  155. package/scripts/rea.mjs +1 -1
  156. package/skills/rea-analysis/SKILL.md +59 -3
@@ -0,0 +1,26 @@
1
+ import { createEvidence, } from "../domain/evidence.js";
2
+ import { jsonValueSchema } from "../domain/jsonValue.js";
3
+ import { JAVASCRIPT_APPLICATION_PROVIDER } from "./InvestigationProviders.js";
4
+ /** Create Evidence v2 for one deterministic local JavaScript application graph. */
5
+ export const createJavaScriptApplicationEvidence = (input, result) => createEvidence({
6
+ path: result.input_path,
7
+ sha256: result.root_artifact_sha256,
8
+ format: result.format,
9
+ }, JAVASCRIPT_APPLICATION_PROVIDER, {
10
+ predicateType: "rea.javascript-application-analysis/v1",
11
+ operation: "analyze_javascript_application",
12
+ parameters: parameters(input),
13
+ result: jsonValueSchema.parse(result),
14
+ rawResult: null,
15
+ confidence: "derived",
16
+ authority: "shipped-artifact",
17
+ environment: null,
18
+ limitations: result.limitations,
19
+ locations: [{ kind: "artifact-path", path: "artifact-root" }],
20
+ });
21
+ const parameters = (input) => ({
22
+ format: input.format,
23
+ approved: input.approved,
24
+ source_map_read_approved: input.source_map_read_approved,
25
+ limits: input.limits,
26
+ });
@@ -0,0 +1,89 @@
1
+ import { JAVASCRIPT_APPLICATION_PROVIDER, JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER, MANAGED_WORKFLOW_PROVIDER, } from "./InvestigationProviders.js";
2
+ import { parseEvidence } from "../domain/evidence.js";
3
+ import { analyzeJavaScriptApplicationInputSchema, javascriptApplicationAnalysisResultSchema, } from "../domain/javascriptApplicationAnalysis.js";
4
+ import { javascriptRuntimeReconciliationResultSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
5
+ import { managedApplicationGraphResultSchema } from "../domain/managedApplicationGraph.js";
6
+ /** Parse and authenticate one REA-produced JavaScript Application Graph Evidence. */
7
+ export const parseApplicationGraphEvidence = (input) => {
8
+ const evidence = parseEvidence(input);
9
+ if (evidence.operation === "analyze_javascript_application" &&
10
+ evidence.predicate_type === "rea.javascript-application-analysis/v1" &&
11
+ providerMatches(evidence, JAVASCRIPT_APPLICATION_PROVIDER))
12
+ return staticApplicationSource(evidence);
13
+ if (evidence.operation === "reconcile_javascript_runtime" &&
14
+ evidence.predicate_type === "rea.javascript-runtime-reconciliation/v1" &&
15
+ providerMatches(evidence, JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER))
16
+ return staticRuntimeSource(evidence);
17
+ if (evidence.operation === "project_managed_application_graph" &&
18
+ evidence.predicate_type === "rea.managed-application-graph/v1" &&
19
+ providerMatches(evidence, MANAGED_WORKFLOW_PROVIDER))
20
+ return managedApplicationSource(evidence);
21
+ throw new TypeError("Application workflow requires authenticated analyze_javascript_application, reconcile_javascript_runtime, or project_managed_application_graph Evidence");
22
+ };
23
+ const staticApplicationSource = (evidence) => {
24
+ if (evidence.authority !== "shipped-artifact" ||
25
+ evidence.confidence !== "derived")
26
+ throw new TypeError("JavaScript application Evidence authority or confidence is invalid");
27
+ const result = javascriptApplicationAnalysisResultSchema.parse(evidence.normalized_result);
28
+ analyzeJavaScriptApplicationInputSchema.parse({
29
+ input_path: result.input_path,
30
+ ...evidence.parameters,
31
+ });
32
+ assertApplicationSubject(evidence, result);
33
+ return {
34
+ evidence,
35
+ graph: result.graph,
36
+ kind: "static-application",
37
+ rootArtifactSha256: result.root_artifact_sha256,
38
+ };
39
+ };
40
+ const staticRuntimeSource = (evidence) => {
41
+ if (evidence.authority !== "analyst-inference" ||
42
+ evidence.confidence !== "inferred")
43
+ throw new TypeError("JavaScript runtime reconciliation Evidence authority or confidence is invalid");
44
+ const result = javascriptRuntimeReconciliationResultSchema.parse(evidence.normalized_result);
45
+ if (result.evidence_links.some((evidenceId) => !evidence.evidence_links.includes(evidenceId)))
46
+ throw new TypeError("Runtime reconciliation result references Evidence outside its envelope");
47
+ const applicationLayer = result.static_layers.find(({ role }) => role === "application");
48
+ if (applicationLayer === undefined)
49
+ throw new TypeError("Runtime reconciliation application layer is missing");
50
+ return {
51
+ evidence,
52
+ graph: result.graph,
53
+ kind: "static-runtime-reconciliation",
54
+ rootArtifactSha256: applicationLayer.root_artifact_sha256,
55
+ };
56
+ };
57
+ const managedApplicationSource = (evidence) => {
58
+ if (evidence.authority !== "analyst-inference" ||
59
+ evidence.confidence !== "inferred")
60
+ throw new TypeError("Managed application graph Evidence authority or confidence is invalid");
61
+ const result = managedApplicationGraphResultSchema.parse(evidence.normalized_result);
62
+ if (result.evidence_links.some((evidenceId) => !evidence.evidence_links.includes(evidenceId)))
63
+ throw new TypeError("Managed application graph result references Evidence outside its envelope");
64
+ return {
65
+ evidence,
66
+ graph: result.graph,
67
+ kind: "managed-application",
68
+ rootArtifactSha256: result.root_artifact_sha256,
69
+ };
70
+ };
71
+ const assertApplicationSubject = (evidence, result) => {
72
+ if (evidence.subject === null ||
73
+ evidence.subject.digest.sha256 !== result.root_artifact_sha256 ||
74
+ evidence.subject.format !== result.format)
75
+ throw new TypeError("JavaScript application Evidence subject does not match its result");
76
+ };
77
+ const providerMatches = (evidence, provider) => evidence.provider.id === provider.id &&
78
+ evidence.provider.name === provider.name &&
79
+ evidence.provider.version === provider.version;
80
+ /** Parse unique, artifact-bound Evidence that may extend a native handoff. */
81
+ export const parseNativeApplicationEvidence = (inputs) => {
82
+ const parsed = inputs.map((input) => parseEvidence(input));
83
+ if (parsed.some(({ subject }) => subject === null))
84
+ throw new TypeError("Native handoff Evidence requires an artifact subject");
85
+ const ids = parsed.map(({ evidence_id: id }) => id);
86
+ if (new Set(ids).size !== ids.length)
87
+ throw new TypeError("Native handoff Evidence must be unique");
88
+ return parsed;
89
+ };
@@ -0,0 +1,74 @@
1
+ import { z } from "zod";
2
+ import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
3
+ import { analyzeJavaScriptApplicationInputSchema, javascriptApplicationAnalysisResultSchema, } from "../domain/javascriptApplicationAnalysis.js";
4
+ import { AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisProtocolError, ArtifactOperationError, PermissionRequiredError, } from "../domain/errors.js";
5
+ import { err, ok } from "../domain/result.js";
6
+ import { createJavaScriptApplicationEvidence } from "./JavaScriptApplicationEvidence.js";
7
+ import { reconstructJavaScriptArtifact } from "./JavaScriptArtifactReconstruction.js";
8
+ const OPERATION = "analyze_javascript_application";
9
+ /** Authorize and statically analyze one local JavaScript/Electron application. */
10
+ export const analyzeJavaScriptApplication = async (authority, rawInput, options = {}) => {
11
+ const parsed = analyzeJavaScriptApplicationInputSchema.safeParse(rawInput);
12
+ if (!parsed.success)
13
+ return err(new AnalysisInputError(OPERATION));
14
+ return analyzeJavaScriptApplicationValidated(authority, parsed.data, options);
15
+ };
16
+ /** Analyze input already parsed by a trusted adapter boundary. */
17
+ export const analyzeJavaScriptApplicationValidated = async (authority, input, options = {}) => {
18
+ if (authority === undefined)
19
+ return err(new AnalysisCapabilityUnavailableError("rea-javascript-application", OPERATION, "JavaScript application permission policy is not configured"));
20
+ const authorized = await authority.authorize({
21
+ capability: "investigation_input",
22
+ roots: [input.input_path],
23
+ executables: [],
24
+ environment_names: [],
25
+ network: "none",
26
+ mount: false,
27
+ operation_identity: `${OPERATION}:${input.input_path}`,
28
+ }, "read");
29
+ if (!authorized.ok)
30
+ return err(authorized.error instanceof PermissionRequiredError
31
+ ? authorized.error
32
+ : new ArtifactOperationError(OPERATION, "path", {
33
+ logicalPath: input.input_path,
34
+ declaredSha256: null,
35
+ calculatedSha256: null,
36
+ unpacked: false,
37
+ }));
38
+ await options.progress?.report({
39
+ phase: "analyze_javascript_application",
40
+ completed: 0,
41
+ total: 1,
42
+ message: "Inventorying and parsing approved application artifacts",
43
+ });
44
+ try {
45
+ const reconstructed = await reconstructJavaScriptArtifact({
46
+ input_path: input.input_path,
47
+ format: input.format,
48
+ source_map_read_approved: input.source_map_read_approved,
49
+ limits: input.limits,
50
+ }, options.signal);
51
+ const { electron_summary: summary, ...application } = reconstructed;
52
+ const result = javascriptApplicationAnalysisResultSchema.parse({
53
+ schema_version: 1,
54
+ ...application,
55
+ summary,
56
+ limitations: reconstructed.graph.limitations,
57
+ });
58
+ await options.progress?.report({
59
+ phase: "analyze_javascript_application",
60
+ completed: 1,
61
+ total: 1,
62
+ message: "Application graph and Electron boundaries reconstructed",
63
+ terminal: true,
64
+ });
65
+ return ok(createJavaScriptApplicationEvidence(input, result));
66
+ }
67
+ catch (cause) {
68
+ if (cause instanceof ArtifactReaderFailure)
69
+ return err(new ArtifactOperationError(OPERATION, cause.reason, cause.details));
70
+ if (cause instanceof z.ZodError)
71
+ return err(new AnalysisProtocolError("JavaScript application analysis produced an invalid result", { cause }));
72
+ return err(new ArtifactOperationError(OPERATION, "io"));
73
+ }
74
+ };
@@ -0,0 +1,29 @@
1
+ import { createEvidence, } from "../domain/evidence.js";
2
+ import { jsonValueSchema } from "../domain/jsonValue.js";
3
+ import { JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER } from "./InvestigationProviders.js";
4
+ /** Create derived Evidence for one bounded application-graph feature trace. */
5
+ export const createApplicationFeatureTraceEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
6
+ predicateType: "rea.application-feature-trace/v1",
7
+ operation: "trace_application_feature",
8
+ parameters,
9
+ result: jsonValueSchema.parse(result),
10
+ rawResult: null,
11
+ confidence: "inferred",
12
+ authority: "analyst-inference",
13
+ environment: null,
14
+ limitations: result.limitations,
15
+ evidenceLinks: result.evidence_links,
16
+ });
17
+ /** Create derived Evidence for one tiered application version comparison. */
18
+ export const createApplicationVersionComparisonEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
19
+ predicateType: "rea.application-version-comparison/v1",
20
+ operation: "compare_application_versions",
21
+ parameters,
22
+ result: jsonValueSchema.parse(result),
23
+ rawResult: null,
24
+ confidence: "inferred",
25
+ authority: "analyst-inference",
26
+ environment: null,
27
+ limitations: result.limitations,
28
+ evidenceLinks: result.evidence_links,
29
+ });
@@ -0,0 +1,90 @@
1
+ import { z } from "zod";
2
+ import { AnalysisInputError, AnalysisProtocolError, } from "../domain/errors.js";
3
+ import { projectInputIssues } from "../domain/inputIssueProjection.js";
4
+ import { compareJavaScriptApplicationVersions } from "../domain/javascriptApplicationVersionComparison.js";
5
+ import { compareApplicationVersionsInputSchema } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
6
+ import { traceApplicationFeature } from "../domain/javascriptFeatureTrace.js";
7
+ import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
8
+ import { err, ok } from "../domain/result.js";
9
+ import { parseApplicationGraphEvidence, parseNativeApplicationEvidence, } from "./JavaScriptApplicationEvidenceGraph.js";
10
+ import { createApplicationFeatureTraceEvidence, createApplicationVersionComparisonEvidence, } from "./JavaScriptApplicationWorkflowEvidence.js";
11
+ /** Authenticate Evidence and derive one bounded cross-layer feature trace. */
12
+ export const traceApplicationFeatureEvidence = (rawInput) => {
13
+ const operation = "trace_application_feature";
14
+ const parsed = traceApplicationFeatureInputSchema.safeParse(rawInput);
15
+ if (!parsed.success)
16
+ return err(new AnalysisInputError(operation, undefined, projectInputIssues(parsed.error.issues, rawInput)));
17
+ return traceApplicationFeatureEvidenceValidated(parsed.data);
18
+ };
19
+ /** Derive one feature trace from input parsed by a trusted adapter. */
20
+ export const traceApplicationFeatureEvidenceValidated = (input) => {
21
+ const operation = "trace_application_feature";
22
+ try {
23
+ const source = parseApplicationGraphEvidence(input.application);
24
+ const nativeEvidence = parseNativeApplicationEvidence(input.native_observations);
25
+ const result = traceApplicationFeature({
26
+ sourceEvidenceId: source.evidence.evidence_id,
27
+ graph: source.graph,
28
+ nativeEvidence,
29
+ seed: input.seed,
30
+ direction: input.direction,
31
+ limits: input.limits,
32
+ });
33
+ return ok(createApplicationFeatureTraceEvidence({
34
+ application_evidence_id: source.evidence.evidence_id,
35
+ native_evidence_ids: nativeEvidence.map(({ evidence_id: id }) => id),
36
+ seed: input.seed,
37
+ direction: input.direction,
38
+ limits: input.limits,
39
+ }, result));
40
+ }
41
+ catch (cause) {
42
+ return workflowFailure(operation, cause);
43
+ }
44
+ };
45
+ /** Authenticate both graphs and derive a tiered cross-version change graph. */
46
+ export const compareApplicationVersionsEvidence = (rawInput) => {
47
+ const operation = "compare_application_versions";
48
+ const parsed = compareApplicationVersionsInputSchema.safeParse(rawInput);
49
+ if (!parsed.success)
50
+ return err(new AnalysisInputError(operation, undefined, projectInputIssues(parsed.error.issues, rawInput)));
51
+ return compareApplicationVersionsEvidenceValidated(parsed.data);
52
+ };
53
+ /** Compare versions from input parsed by a trusted adapter. */
54
+ export const compareApplicationVersionsEvidenceValidated = (input) => {
55
+ const operation = "compare_application_versions";
56
+ try {
57
+ const left = parseApplicationGraphEvidence(input.left);
58
+ const right = parseApplicationGraphEvidence(input.right);
59
+ const leftNative = parseNativeApplicationEvidence(input.left_native_observations);
60
+ const rightNative = parseNativeApplicationEvidence(input.right_native_observations);
61
+ const result = compareJavaScriptApplicationVersions({
62
+ left: {
63
+ evidenceId: left.evidence.evidence_id,
64
+ rootArtifactSha256: left.rootArtifactSha256,
65
+ graph: left.graph,
66
+ },
67
+ right: {
68
+ evidenceId: right.evidence.evidence_id,
69
+ rootArtifactSha256: right.rootArtifactSha256,
70
+ graph: right.graph,
71
+ },
72
+ leftNativeEvidence: leftNative,
73
+ rightNativeEvidence: rightNative,
74
+ limits: input.limits,
75
+ });
76
+ return ok(createApplicationVersionComparisonEvidence({
77
+ left_evidence_id: left.evidence.evidence_id,
78
+ right_evidence_id: right.evidence.evidence_id,
79
+ left_native_evidence_ids: leftNative.map(({ evidence_id: id }) => id),
80
+ right_native_evidence_ids: rightNative.map(({ evidence_id: id }) => id),
81
+ limits: input.limits,
82
+ }, result));
83
+ }
84
+ catch (cause) {
85
+ return workflowFailure(operation, cause);
86
+ }
87
+ };
88
+ const workflowFailure = (operation, cause) => err(cause instanceof z.ZodError || cause instanceof TypeError
89
+ ? new AnalysisInputError(operation)
90
+ : new AnalysisProtocolError("JavaScript application workflow produced an invalid result", { cause }));
@@ -284,7 +284,13 @@ const findingCount = (analysis) => analysis.references.length +
284
284
  analysis.storage.length +
285
285
  analysis.role_paths.length +
286
286
  analysis.source_map_urls.length +
287
- analysis.bundler_registrations.length;
287
+ analysis.bundler_registrations.length +
288
+ analysis.electron.browser_windows.length +
289
+ analysis.electron.context_bridge_apis.length +
290
+ analysis.electron.ipc.length +
291
+ analysis.electron.sender_validations.length +
292
+ analysis.electron.utility_processes.length +
293
+ analysis.electron.native_addon_bindings.length;
288
294
  const rangeForOffsets = (text, start, end) => ({
289
295
  start: pointForOffset(text, start),
290
296
  end: pointForOffset(text, end),
@@ -5,6 +5,8 @@ import { addJavaScriptHtmlRoles, addJavaScriptSourceMapOriginals, } from "./Java
5
5
  import { addJavaScriptStaticFindings } from "./JavaScriptArtifactGraphFindings.js";
6
6
  import { completeReconstructionCoverage, partialReconstructionCoverage, } from "./JavaScriptArtifactGraphEvidence.js";
7
7
  import { addJavaScriptArtifactContainers, addJavaScriptArtifactFiles, addJavaScriptBundlerNodes, addJavaScriptPackageNodes, createJavaScriptArtifactRootNode, } from "./JavaScriptArtifactGraphStructure.js";
8
+ import { addElectronBoundaries } from "./ElectronBoundaryGraph.js";
9
+ import { classifyElectronIpcPairings, collectElectronIpcRecords, } from "./ElectronBoundaryAnalysis.js";
8
10
  /** Project bounded artifact and AST facts into JavaScript Application Graph v1. */
9
11
  export const buildJavaScriptArtifactGraph = (snapshot, fileSet, analysis, input) => {
10
12
  const accumulator = new JavaScriptArtifactGraphAccumulator();
@@ -27,6 +29,7 @@ export const buildJavaScriptArtifactGraph = (snapshot, fileSet, analysis, input)
27
29
  const packageRoots = addJavaScriptPackageNodes(context);
28
30
  addJavaScriptBundlerNodes(context);
29
31
  addJavaScriptStaticFindings(context);
32
+ addElectronBoundaries(context);
30
33
  addJavaScriptHtmlRoles(context);
31
34
  addJavaScriptSourceMapOriginals(context);
32
35
  const coverage = graphCoverage(context);
@@ -48,10 +51,12 @@ const graphCoverage = (context) => {
48
51
  const sourceMapPolicyGap = context.analysis.source_maps.some(({ status }) => status === "not-approved");
49
52
  const malformedStructuredData = context.analysis.packages.some(({ status }) => status !== "included") ||
50
53
  context.analysis.source_maps.some(({ status }) => status === "invalid");
54
+ const partialJavaScript = context.analysis.files.some(({ javascript }) => javascript !== null && javascript.parse_status === "partial");
51
55
  const unknownGap = context.analysis.parse_failures > 0 ||
52
56
  context.fileSet.invalid_utf8_files > 0 ||
53
57
  sourceMapPolicyGap ||
54
- malformedStructuredData;
58
+ malformedStructuredData ||
59
+ partialJavaScript;
55
60
  if (context.analysis.truncated_scopes > 0)
56
61
  return partialReconstructionCoverage(reconstructionLimits(context.input), null, true);
57
62
  if (exactLimitOmissions > 0)
@@ -60,21 +65,59 @@ const graphCoverage = (context) => {
60
65
  return partialReconstructionCoverage(reconstructionLimits(context.input), null, false);
61
66
  return completeReconstructionCoverage(reconstructionLimits(context.input));
62
67
  };
63
- const graphLimitations = (context, coverage) => [
64
- ...context.analysis.limitations,
65
- "Webpack/Rspack factories were recovered from AST literals; REA did not invoke push handlers or bundle bootstrap code.",
66
- "Static imports, entrypoints, workers, endpoints, and storage relationships do not prove runtime execution.",
67
- ...(context.accumulator.omittedObservations() === 0
68
- ? []
69
- : [
70
- "Repeated content identities exceeded the per-node observation bound; containment edges still preserve inventoried paths.",
71
- ]),
72
- ...(coverage === "complete"
73
- ? []
74
- : [
75
- "Graph coverage is incomplete; unavailable facts remain explicit and must not be read as absence.",
76
- ]),
77
- ];
68
+ const graphLimitations = (context, coverage) => {
69
+ const ipc = collectElectronIpcRecords(context.analysis);
70
+ const pairings = classifyElectronIpcPairings(ipc);
71
+ const electronFindings = context.analysis.files.reduce((count, { javascript }) => count +
72
+ (javascript === null
73
+ ? 0
74
+ : javascript.electron.browser_windows.length +
75
+ javascript.electron.context_bridge_apis.length +
76
+ javascript.electron.ipc.length +
77
+ javascript.electron.sender_validations.length +
78
+ javascript.electron.utility_processes.length +
79
+ javascript.electron.native_addon_bindings.length), 0);
80
+ return [
81
+ ...context.analysis.limitations,
82
+ "Webpack/Rspack factories were recovered from AST literals; REA did not invoke push handlers or bundle bootstrap code.",
83
+ "Static imports, entrypoints, workers, endpoints, and storage relationships do not prove runtime execution.",
84
+ ...(electronFindings === 0
85
+ ? []
86
+ : [
87
+ "Electron relationships are derived from inert syntax; runtime registration, reachability, defaults, and enforcement remain unproven.",
88
+ ]),
89
+ ...(ipc.some(({ finding }) => finding.channel === null)
90
+ ? [
91
+ "Dynamic IPC channel expressions remain unresolved and are never paired by textual similarity.",
92
+ ]
93
+ : []),
94
+ ...(pairings.some(({ status }) => status === "ambiguous")
95
+ ? [
96
+ "Some literal IPC channels have multiple compatible main handlers; ambiguous calls are not paired to any handler.",
97
+ ]
98
+ : []),
99
+ ...(context.analysis.files.some(({ javascript }) => (javascript?.electron.sender_validations.length ?? 0) > 0)
100
+ ? [
101
+ "Sender, frame, URL, and origin checks are observations only; REA does not claim that they enforce a complete authorization policy.",
102
+ ]
103
+ : []),
104
+ ...(context.analysis.files.some(({ javascript }) => (javascript?.electron.native_addon_bindings.length ?? 0) > 0)
105
+ ? [
106
+ "Native member names are requested by JavaScript syntax and are not verified binary exports in this workflow.",
107
+ ]
108
+ : []),
109
+ ...(context.accumulator.omittedObservations() === 0
110
+ ? []
111
+ : [
112
+ "Repeated content identities exceeded the per-node observation bound; containment edges still preserve inventoried paths.",
113
+ ]),
114
+ ...(coverage === "complete"
115
+ ? []
116
+ : [
117
+ "Graph coverage is incomplete; unavailable facts remain explicit and must not be read as absence.",
118
+ ]),
119
+ ];
120
+ };
78
121
  const reconstructionLimits = (input) => [
79
122
  {
80
123
  name: "max-entries",
@@ -19,20 +19,30 @@ export const artifactObservationEvidence = (input) => ({
19
19
  evidence_ids: [],
20
20
  });
21
21
  /** Exact AST syntax evidence with an actionable source range. */
22
- export const astObservationEvidence = (input) => ({
23
- authority: "ast-static-analysis",
24
- state: "observed",
25
- confidence: "exact",
26
- artifact: artifactReference(input.sha256),
27
- location: {
28
- available: true,
29
- value: { kind: "source-range", source: input.path, ...input.range },
30
- },
31
- extractor: { ...EXTRACTOR, operation: input.operation },
32
- coverage: input.coverage,
33
- limitations: [...(input.limitations ?? [])],
34
- evidence_ids: [],
35
- });
22
+ export const astObservationEvidence = (input) => {
23
+ const limitations = [
24
+ ...(input.limitations ?? []),
25
+ ...(input.coverage.status === "complete"
26
+ ? []
27
+ : [
28
+ "AST coverage is incomplete; omitted or dynamic facts must not be interpreted as absence.",
29
+ ]),
30
+ ];
31
+ return {
32
+ authority: "ast-static-analysis",
33
+ state: "observed",
34
+ confidence: "exact",
35
+ artifact: artifactReference(input.sha256),
36
+ location: {
37
+ available: true,
38
+ value: { kind: "source-range", source: input.path, ...input.range },
39
+ },
40
+ extractor: { ...EXTRACTOR, operation: input.operation },
41
+ coverage: input.coverage,
42
+ limitations,
43
+ evidence_ids: [],
44
+ };
45
+ };
36
46
  /** Explicit static relationship inference; never promoted to observation. */
37
47
  export const staticInferenceEvidence = (input) => ({
38
48
  authority: "static-relationship-inference",
@@ -8,6 +8,7 @@ import { readJavaScriptArtifactFiles } from "./JavaScriptArtifactFiles.js";
8
8
  import { buildJavaScriptArtifactGraph } from "./JavaScriptArtifactGraphBuilder.js";
9
9
  import { artifactLimitsForReconstruction, javascriptArtifactReconstructionInputSchema, } from "./JavaScriptArtifactReconstructionInput.js";
10
10
  import { scanCanonicalArtifactInventory } from "./ArtifactInventory.js";
11
+ import { summarizeElectronBoundaries } from "./ElectronBoundaryAnalysis.js";
11
12
  /** Reconstruct one local ASAR or extracted directory without executing code. */
12
13
  export const reconstructJavaScriptArtifact = async (rawInput, signal) => {
13
14
  const input = javascriptArtifactReconstructionInputSchema.parse(rawInput);
@@ -26,9 +27,11 @@ export const reconstructJavaScriptArtifact = async (rawInput, signal) => {
26
27
  return {
27
28
  input_path: path,
28
29
  format,
30
+ root_artifact_sha256: snapshot.manifest.root_sha256,
29
31
  inventory_manifest_id: snapshot.manifest.manifest_id,
30
32
  inventory_graph_sha256: snapshot.manifest.graph_sha256,
31
33
  graph,
34
+ electron_summary: summarizeElectronBoundaries(analysis),
32
35
  statistics: {
33
36
  relevant_files: files.files.length,
34
37
  nested_asar_containers: files.containers.length,
@@ -1,92 +1,11 @@
1
1
  import { z } from "zod";
2
- const MAX_GRAPH_NODES = 100_000;
3
- const MAX_GRAPH_EDGES = 200_000;
4
- const reconstructionLimitsSchema = z
5
- .strictObject({
6
- max_entries: z.number().int().min(1).max(1_000_000).default(8_000),
7
- max_total_artifact_bytes: z
8
- .number()
9
- .int()
10
- .min(1)
11
- .max(Number.MAX_SAFE_INTEGER)
12
- .default(512 * 1_024 * 1_024),
13
- max_artifact_entry_bytes: z
14
- .number()
15
- .int()
16
- .min(1)
17
- .max(Number.MAX_SAFE_INTEGER)
18
- .default(128 * 1_024 * 1_024),
19
- max_compression_ratio: z.number().min(1).max(100_000).default(1_000),
20
- max_depth: z.number().int().min(1).max(100).default(64),
21
- max_path_bytes: z.number().int().min(1).max(65_535).default(4_096),
22
- max_text_files: z.number().int().min(1).max(100_000).default(5_000),
23
- max_total_text_bytes: z
24
- .number()
25
- .int()
26
- .min(1)
27
- .max(512 * 1_024 * 1_024)
28
- .default(128 * 1_024 * 1_024),
29
- max_text_file_bytes: z
30
- .number()
31
- .int()
32
- .min(1)
33
- .max(64 * 1_024 * 1_024)
34
- .default(8 * 1_024 * 1_024),
35
- max_ast_nodes: z.number().int().min(1).max(20_000_000).default(2_000_000),
36
- max_findings: z.number().int().min(1).max(200_000).default(10_000),
37
- max_modules: z.number().int().min(1).max(100_000).default(20_000),
38
- max_source_map_sources: z.number().int().min(1).max(100_000).default(5_000),
39
- max_parse_milliseconds: z
40
- .number()
41
- .int()
42
- .min(1)
43
- .max(300_000)
44
- .default(30_000),
45
- })
46
- .superRefine((limits, context) => {
47
- const projectedNodes = 7 * limits.max_entries +
48
- limits.max_findings +
49
- limits.max_modules +
50
- limits.max_source_map_sources +
51
- 1;
52
- if (projectedNodes > MAX_GRAPH_NODES)
53
- context.addIssue({
54
- code: "custom",
55
- path: ["max_entries"],
56
- message: "Combined reconstruction limits can exceed the 100000-node graph contract",
57
- });
58
- const projectedEdges = 9 * limits.max_entries +
59
- 5 * limits.max_findings +
60
- limits.max_modules +
61
- limits.max_source_map_sources;
62
- if (projectedEdges > MAX_GRAPH_EDGES)
63
- context.addIssue({
64
- code: "custom",
65
- path: ["max_entries"],
66
- message: "Combined reconstruction limits can exceed the 200000-edge graph contract",
67
- });
68
- });
2
+ import { JAVASCRIPT_APPLICATION_ANALYSIS_DEFAULT_LIMITS, javascriptApplicationAnalysisLimitsSchema, } from "../domain/javascriptApplicationAnalysis.js";
69
3
  /** Local ASAR/directory reconstruction request with explicit source-map authority. */
70
4
  export const javascriptArtifactReconstructionInputSchema = z.strictObject({
71
5
  input_path: z.string().min(1).max(16_384),
72
6
  format: z.enum(["auto", "asar", "directory"]).default("auto"),
73
7
  source_map_read_approved: z.boolean().default(false),
74
- limits: reconstructionLimitsSchema.default({
75
- max_entries: 8_000,
76
- max_total_artifact_bytes: 512 * 1_024 * 1_024,
77
- max_artifact_entry_bytes: 128 * 1_024 * 1_024,
78
- max_compression_ratio: 1_000,
79
- max_depth: 64,
80
- max_path_bytes: 4_096,
81
- max_text_files: 5_000,
82
- max_total_text_bytes: 128 * 1_024 * 1_024,
83
- max_text_file_bytes: 8 * 1_024 * 1_024,
84
- max_ast_nodes: 2_000_000,
85
- max_findings: 10_000,
86
- max_modules: 20_000,
87
- max_source_map_sources: 5_000,
88
- max_parse_milliseconds: 30_000,
89
- }),
8
+ limits: javascriptApplicationAnalysisLimitsSchema.default(JAVASCRIPT_APPLICATION_ANALYSIS_DEFAULT_LIMITS),
90
9
  });
91
10
  /** Project reconstruction limits into the shared artifact traversal policy. */
92
11
  export const artifactLimitsForReconstruction = (input) => ({