resolve-solo 1.2.1 → 1.2.3

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.
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Natural Language Query Parser
3
+ *
4
+ * Extracts entities, intent, and context from investigation queries.
5
+ */
6
+ // Common service name patterns
7
+ const KNOWN_SERVICES = [
8
+ 'api-gateway', 'api gateway', 'apigateway',
9
+ 'payment-service', 'payment service', 'payments',
10
+ 'auth-service', 'auth service', 'authentication',
11
+ 'config-service', 'config service',
12
+ 'user-service', 'user service', 'users',
13
+ 'order-service', 'order service', 'orders',
14
+ 'notification-service', 'notification service', 'notifications',
15
+ 'brokerage', 'brokerage-service', 'brokerage service',
16
+ 'financing', 'financing-service', 'financing service',
17
+ 'portfolio', 'portfolio-service', 'portfolio service',
18
+ 'trading', 'trading-service', 'trading service',
19
+ 'redis', 'redis-cache', 'cache',
20
+ 'postgres', 'postgresql', 'database', 'db',
21
+ 'kafka', 'message-queue', 'mq',
22
+ 'kubernetes', 'k8s',
23
+ 'nginx', 'load-balancer', 'lb',
24
+ ];
25
+ // Normalize service names to canonical form
26
+ const SERVICE_ALIASES = {
27
+ 'api gateway': 'api-gateway',
28
+ 'apigateway': 'api-gateway',
29
+ 'payment service': 'payment-service',
30
+ 'payments': 'payment-service',
31
+ 'auth service': 'auth-service',
32
+ 'authentication': 'auth-service',
33
+ 'config service': 'config-service',
34
+ 'user service': 'user-service',
35
+ 'users': 'user-service',
36
+ 'order service': 'order-service',
37
+ 'orders': 'order-service',
38
+ 'notification service': 'notification-service',
39
+ 'notifications': 'notification-service',
40
+ 'brokerage service': 'brokerage-service',
41
+ 'brokerage': 'brokerage-service',
42
+ 'financing service': 'financing-service',
43
+ 'financing': 'financing-service',
44
+ 'portfolio service': 'portfolio-service',
45
+ 'portfolio': 'portfolio-service',
46
+ 'trading service': 'trading-service',
47
+ 'trading': 'trading-service',
48
+ 'redis-cache': 'redis',
49
+ 'cache': 'redis',
50
+ 'postgresql': 'postgres',
51
+ 'database': 'postgres',
52
+ 'db': 'postgres',
53
+ 'message-queue': 'kafka',
54
+ 'mq': 'kafka',
55
+ 'k8s': 'kubernetes',
56
+ 'load-balancer': 'nginx',
57
+ 'lb': 'nginx',
58
+ };
59
+ // Intent detection patterns
60
+ const INTENT_PATTERNS = [
61
+ // Help/meta queries
62
+ { pattern: /what can i ask|what.*available|help me|what.*resolve/i, intent: 'help' },
63
+ // Logs
64
+ { pattern: /error logs?|show.*logs?|logs? for/i, intent: 'logs' },
65
+ { pattern: /errors? in|exceptions?|stack trace/i, intent: 'logs' },
66
+ // Metrics
67
+ { pattern: /latency|throughput|p99|p95|p50|response time/i, intent: 'metrics' },
68
+ { pattern: /metrics?|trends?|performance/i, intent: 'metrics' },
69
+ { pattern: /error rate|success rate|availability/i, intent: 'metrics' },
70
+ // Changes
71
+ { pattern: /code changes?|what changed|changes? (to|in|for)/i, intent: 'changes' },
72
+ { pattern: /commits?|pull requests?|prs?|merged/i, intent: 'changes' },
73
+ // Deployments
74
+ { pattern: /deploy(ed|ment|s)?|released?|rolled out/i, intent: 'deployments' },
75
+ { pattern: /what.*shipped|went (live|out)/i, intent: 'deployments' },
76
+ // Dependencies - check before config since "config-service" contains "config"
77
+ { pattern: /depend(s|encies|ency)?(\s+on)?|upstream|downstream/i, intent: 'dependencies' },
78
+ { pattern: /what.*calls?|connects? to|uses?/i, intent: 'dependencies' },
79
+ // Config - be specific to avoid matching service names like "config-service"
80
+ { pattern: /config(uration)?\s+(changes?|history|settings?)/i, intent: 'config' },
81
+ { pattern: /kubernetes|k8s|helm|yaml/i, intent: 'config' },
82
+ { pattern: /\bsettings?\b|\benvironment\b|env vars?/i, intent: 'config' },
83
+ ];
84
+ // Time range patterns
85
+ const TIME_PATTERNS = [
86
+ { pattern: /past (\d+) hours?/i, hours: -1, description: '' }, // Dynamic
87
+ { pattern: /last (\d+) hours?/i, hours: -1, description: '' },
88
+ { pattern: /past (\d+) days?/i, hours: -1, description: '' },
89
+ { pattern: /last (\d+) days?/i, hours: -1, description: '' },
90
+ { pattern: /past (\d+) weeks?/i, hours: -1, description: '' },
91
+ { pattern: /last (\d+) weeks?/i, hours: -1, description: '' },
92
+ { pattern: /today/i, hours: 24, description: 'today' },
93
+ { pattern: /yesterday/i, hours: 48, description: 'since yesterday' },
94
+ { pattern: /this week/i, hours: 168, description: 'this week' },
95
+ { pattern: /last week/i, hours: 336, description: 'last week' },
96
+ ];
97
+ // Date patterns like "January 23rd", "Jan 23", "2024-01-23"
98
+ const SPECIFIC_DATE_PATTERN = /(?:january|february|march|april|may|june|july|august|september|october|november|december|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\s+\d{1,2}(?:st|nd|rd|th)?(?:,?\s*\d{4})?|\d{4}-\d{2}-\d{2}/i;
99
+ // Environment patterns
100
+ const ENVIRONMENT_PATTERNS = [
101
+ { pattern: /\bprod(uction)?\b/i, env: 'production' },
102
+ { pattern: /\bstag(ing|e)?\b/i, env: 'staging' },
103
+ { pattern: /\bdev(elopment)?\b/i, env: 'development' },
104
+ { pattern: /\btest(ing)?\b/i, env: 'testing' },
105
+ ];
106
+ /**
107
+ * Parse a natural language query into structured components
108
+ */
109
+ export function parseQuery(query) {
110
+ const lowerQuery = query.toLowerCase();
111
+ return {
112
+ intent: detectIntent(lowerQuery),
113
+ services: extractServices(lowerQuery),
114
+ timeRange: extractTimeRange(query),
115
+ environment: extractEnvironment(lowerQuery),
116
+ keywords: extractKeywords(lowerQuery),
117
+ originalQuery: query,
118
+ };
119
+ }
120
+ /**
121
+ * Detect the primary intent of the query
122
+ */
123
+ function detectIntent(query) {
124
+ for (const { pattern, intent } of INTENT_PATTERNS) {
125
+ if (pattern.test(query)) {
126
+ return intent;
127
+ }
128
+ }
129
+ return 'investigate'; // Default to general investigation
130
+ }
131
+ /**
132
+ * Extract service names from the query
133
+ */
134
+ function extractServices(query) {
135
+ const found = new Set();
136
+ for (const service of KNOWN_SERVICES) {
137
+ if (query.includes(service.toLowerCase())) {
138
+ // Normalize to canonical name
139
+ const canonical = SERVICE_ALIASES[service] || service;
140
+ found.add(canonical);
141
+ }
142
+ }
143
+ // If no services found, return empty (will use context or default)
144
+ return Array.from(found);
145
+ }
146
+ /**
147
+ * Extract time range from the query
148
+ */
149
+ function extractTimeRange(query) {
150
+ const lowerQuery = query.toLowerCase();
151
+ // Check for specific date mentions
152
+ const dateMatch = SPECIFIC_DATE_PATTERN.exec(query);
153
+ if (dateMatch) {
154
+ const parsedDate = parseSpecificDate(dateMatch[0]);
155
+ if (parsedDate) {
156
+ const now = new Date();
157
+ const hours = Math.ceil((now.getTime() - parsedDate.getTime()) / (1000 * 60 * 60));
158
+ return {
159
+ description: `since ${dateMatch[0]}`,
160
+ startDate: parsedDate,
161
+ endDate: now,
162
+ hours: Math.max(hours, 24), // At least 24 hours
163
+ };
164
+ }
165
+ }
166
+ // Check for relative time patterns
167
+ for (const { pattern } of TIME_PATTERNS) {
168
+ const match = pattern.exec(lowerQuery);
169
+ if (match) {
170
+ const num = parseInt(match[1]) || 1;
171
+ let hours;
172
+ let description;
173
+ if (/hours?/.test(match[0])) {
174
+ hours = num;
175
+ description = `past ${num} hour${num > 1 ? 's' : ''}`;
176
+ }
177
+ else if (/days?/.test(match[0])) {
178
+ hours = num * 24;
179
+ description = `past ${num} day${num > 1 ? 's' : ''}`;
180
+ }
181
+ else if (/weeks?/.test(match[0])) {
182
+ hours = num * 168;
183
+ description = `past ${num} week${num > 1 ? 's' : ''}`;
184
+ }
185
+ else if (/today/.test(match[0])) {
186
+ hours = 24;
187
+ description = 'today';
188
+ }
189
+ else if (/yesterday/.test(match[0])) {
190
+ hours = 48;
191
+ description = 'since yesterday';
192
+ }
193
+ else {
194
+ hours = 48;
195
+ description = 'past 2 days';
196
+ }
197
+ const now = new Date();
198
+ return {
199
+ description,
200
+ startDate: new Date(now.getTime() - hours * 60 * 60 * 1000),
201
+ endDate: now,
202
+ hours,
203
+ };
204
+ }
205
+ }
206
+ // Default: last 48 hours
207
+ const now = new Date();
208
+ return {
209
+ description: 'past 48 hours',
210
+ startDate: new Date(now.getTime() - 48 * 60 * 60 * 1000),
211
+ endDate: now,
212
+ hours: 48,
213
+ };
214
+ }
215
+ /**
216
+ * Parse a specific date string
217
+ */
218
+ function parseSpecificDate(dateStr) {
219
+ try {
220
+ // Handle "January 23rd" format
221
+ const cleaned = dateStr.replace(/(st|nd|rd|th)/i, '');
222
+ const parsed = new Date(cleaned);
223
+ if (!isNaN(parsed.getTime())) {
224
+ // If no year specified, assume current year
225
+ if (!/\d{4}/.test(dateStr)) {
226
+ parsed.setFullYear(new Date().getFullYear());
227
+ }
228
+ return parsed;
229
+ }
230
+ }
231
+ catch {
232
+ // Fall through
233
+ }
234
+ return null;
235
+ }
236
+ /**
237
+ * Extract environment from the query
238
+ */
239
+ function extractEnvironment(query) {
240
+ for (const { pattern, env } of ENVIRONMENT_PATTERNS) {
241
+ if (pattern.test(query)) {
242
+ return env;
243
+ }
244
+ }
245
+ return undefined;
246
+ }
247
+ /**
248
+ * Extract keywords for search
249
+ */
250
+ function extractKeywords(query) {
251
+ // Remove common words and extract meaningful terms
252
+ const stopWords = new Set([
253
+ 'show', 'me', 'the', 'a', 'an', 'in', 'on', 'for', 'to', 'of', 'and', 'or',
254
+ 'what', 'which', 'where', 'when', 'how', 'why', 'is', 'are', 'was', 'were',
255
+ 'has', 'have', 'had', 'been', 'be', 'being', 'do', 'does', 'did', 'doing',
256
+ 'can', 'could', 'would', 'should', 'will', 'shall', 'may', 'might', 'must',
257
+ 'past', 'last', 'recent', 'latest', 'new', 'old', 'first', 'second',
258
+ 'days', 'day', 'hours', 'hour', 'minutes', 'minute', 'weeks', 'week',
259
+ ]);
260
+ const words = query.toLowerCase().split(/\s+/);
261
+ return words.filter(word => word.length > 2 &&
262
+ !stopWords.has(word) &&
263
+ !/^\d+$/.test(word));
264
+ }
265
+ /**
266
+ * Generate a human-readable interpretation of the parsed query
267
+ */
268
+ export function describeQuery(parsed) {
269
+ const parts = [];
270
+ // Intent
271
+ const intentDescriptions = {
272
+ investigate: 'Investigating',
273
+ logs: 'Searching logs for',
274
+ metrics: 'Analyzing metrics for',
275
+ changes: 'Finding changes in',
276
+ deployments: 'Checking deployments for',
277
+ dependencies: 'Mapping dependencies of',
278
+ config: 'Reviewing configuration for',
279
+ help: 'Available queries',
280
+ };
281
+ parts.push(intentDescriptions[parsed.intent]);
282
+ // Services
283
+ if (parsed.services.length > 0) {
284
+ parts.push(parsed.services.join(', '));
285
+ }
286
+ else {
287
+ parts.push('all services');
288
+ }
289
+ // Environment
290
+ if (parsed.environment) {
291
+ parts.push(`in ${parsed.environment}`);
292
+ }
293
+ // Time range
294
+ parts.push(`(${parsed.timeRange.description})`);
295
+ return parts.join(' ');
296
+ }
297
+ /**
298
+ * Get available query examples based on connected data sources
299
+ */
300
+ export function getAvailableQueries() {
301
+ return [
302
+ // Logs
303
+ 'Show me error logs for [service-name] in the past 2 days',
304
+ 'What errors occurred in production yesterday?',
305
+ // Metrics
306
+ 'Show me latency trends for [service-name] in the past 24 hours',
307
+ 'What is the error rate for [service-name]?',
308
+ 'Show me p99 latency for the API gateway',
309
+ // Changes
310
+ 'What code changes were deployed to [service-name] on [date]?',
311
+ 'Show me recent commits to the payment service',
312
+ 'What changed in the last 2 hours?',
313
+ // Deployments
314
+ 'What was deployed to production today?',
315
+ 'Show me deployment history for [service-name]',
316
+ // Config
317
+ 'Show me Kubernetes configuration changes in production',
318
+ 'What config changes happened in the past week?',
319
+ // Dependencies
320
+ 'What services depend on [service-name]?',
321
+ 'What does [service-name] connect to?',
322
+ // General investigation
323
+ 'Investigate timeouts on [service-name]',
324
+ 'Why is [service-name] slow?',
325
+ 'Debug connection errors in [service-name]',
326
+ ];
327
+ }
328
+ //# sourceMappingURL=query-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-parser.js","sourceRoot":"","sources":["../src/query-parser.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"realistic-findings.d.ts","sourceRoot":"","sources":["../src/realistic-findings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA4B,UAAU,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAwB,MAAM,sBAAsB,CAAC;AAGtE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,uBAAuB,GAC/B,UAAU,CA2DZ"}
1
+ {"version":3,"file":"realistic-findings.d.ts","sourceRoot":"","sources":["../src/realistic-findings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA4B,UAAU,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAwB,MAAM,sBAAsB,CAAC;AAItE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,uBAAuB,GAC/B,UAAU,CAsEZ"}
@@ -5,19 +5,17 @@
5
5
  * commits, and realistic metrics data.
6
6
  */
7
7
  import { SeededRandom } from './seeded-random.js';
8
+ import { parseQuery } from './query-parser.js';
8
9
  /**
9
10
  * Generate realistic findings for a task based on mock repo context
10
11
  */
11
12
  export function generateRealisticFindings(task, context) {
12
13
  const random = new SeededRandom(context.seed + hashString(task.id));
13
14
  const findings = [];
14
- const queryLower = context.query.toLowerCase();
15
- // Determine target service from query
16
- let targetService = 'api-gateway';
17
- if (queryLower.includes('payment'))
18
- targetService = 'payment-service';
19
- if (queryLower.includes('auth'))
20
- targetService = 'auth-service';
15
+ // Parse query for context-aware findings
16
+ const parsed = parseQuery(context.query);
17
+ const targetService = parsed.services[0] || 'api-gateway';
18
+ const timeRange = parsed.timeRange;
21
19
  switch (task.id) {
22
20
  case 'task-git-scan':
23
21
  findings.push(...generateGitFindings(context.repo, targetService, random));
@@ -49,6 +47,15 @@ export function generateRealisticFindings(task, context) {
49
47
  case 'task-ticket-search':
50
48
  findings.push(...generateTicketFindings(targetService, context.query, random));
51
49
  break;
50
+ case 'task-error-logs':
51
+ findings.push(...generateErrorLogFindings(targetService, timeRange, random));
52
+ break;
53
+ case 'task-config-changes':
54
+ findings.push(...generateConfigFindings(targetService, timeRange, random));
55
+ break;
56
+ case 'task-dependencies':
57
+ findings.push(...generateDependencyFindings(targetService, random));
58
+ break;
52
59
  }
53
60
  return {
54
61
  findings,
@@ -575,6 +582,170 @@ function generateTicketFindings(service, query, random) {
575
582
  });
576
583
  return findings;
577
584
  }
585
+ /**
586
+ * Generate error log findings
587
+ */
588
+ function generateErrorLogFindings(service, timeRange, random) {
589
+ const findings = [];
590
+ const errorTypes = [
591
+ { type: 'NullPointerException', severity: 'P1', count: Math.round(random.next() * 50) + 10 },
592
+ { type: 'ConnectionTimeout', severity: 'P1', count: Math.round(random.next() * 30) + 5 },
593
+ { type: 'AuthenticationError', severity: 'P2', count: Math.round(random.next() * 20) + 2 },
594
+ { type: 'RateLimitExceeded', severity: 'P2', count: Math.round(random.next() * 15) + 1 },
595
+ ];
596
+ const primaryError = errorTypes[Math.floor(random.next() * errorTypes.length)];
597
+ findings.push({
598
+ priority: primaryError.severity,
599
+ title: `Logs: ${primaryError.count} ${primaryError.type} errors (${timeRange.description})`,
600
+ description: `Found ${primaryError.count} instances of ${primaryError.type} in ${service} logs`,
601
+ service,
602
+ source: 'cloudwatch',
603
+ category: 'errors',
604
+ evidence: [
605
+ `Error type: ${primaryError.type}`,
606
+ `Count: ${primaryError.count} in ${timeRange.description}`,
607
+ `First occurrence: ${Math.round(random.next() * timeRange.hours)}h ago`,
608
+ `Last occurrence: ${Math.round(random.next() * 2)}h ago`,
609
+ ],
610
+ suggestedAction: `Investigate ${primaryError.type} in ${service} - check recent code changes`,
611
+ });
612
+ // Summary finding
613
+ const totalErrors = errorTypes.reduce((sum, e) => sum + e.count, 0);
614
+ findings.push({
615
+ priority: 'P3',
616
+ title: `Logs: ${totalErrors} total errors in ${service} (${timeRange.description})`,
617
+ description: `Error breakdown across ${errorTypes.length} error types`,
618
+ service,
619
+ source: 'cloudwatch',
620
+ category: 'errors',
621
+ evidence: errorTypes.map(e => `${e.type}: ${e.count}`),
622
+ suggestedAction: 'Review error distribution for patterns',
623
+ });
624
+ return findings;
625
+ }
626
+ /**
627
+ * Generate Kubernetes/config change findings
628
+ */
629
+ function generateConfigFindings(service, timeRange, random) {
630
+ const findings = [];
631
+ const configChanges = [
632
+ { resource: 'Deployment', field: 'replicas', oldValue: '3', newValue: '5' },
633
+ { resource: 'ConfigMap', field: 'MAX_CONNECTIONS', oldValue: '100', newValue: '200' },
634
+ { resource: 'HPA', field: 'maxReplicas', oldValue: '10', newValue: '15' },
635
+ { resource: 'Ingress', field: 'rate-limit', oldValue: '1000/s', newValue: '500/s' },
636
+ ];
637
+ const change = configChanges[Math.floor(random.next() * configChanges.length)];
638
+ const hoursAgo = Math.round(random.next() * Math.min(timeRange.hours, 24)) + 1;
639
+ findings.push({
640
+ priority: 'P2',
641
+ title: `K8s: ${change.resource} changed ${hoursAgo}h ago`,
642
+ description: `${service} ${change.resource} ${change.field} changed from ${change.oldValue} to ${change.newValue}`,
643
+ service,
644
+ source: 'kubernetes',
645
+ category: 'configuration',
646
+ evidence: [
647
+ `Resource: ${change.resource}/${service}`,
648
+ `Field: ${change.field}`,
649
+ `Change: ${change.oldValue} → ${change.newValue}`,
650
+ `Changed by: platform-bot via ArgoCD`,
651
+ `Time: ${hoursAgo}h ago`,
652
+ ],
653
+ suggestedAction: `Review if ${change.resource} change correlates with the issue`,
654
+ });
655
+ // Helm release info
656
+ findings.push({
657
+ priority: 'P3',
658
+ title: `K8s: ${service} running helm chart v2.4.1`,
659
+ description: 'Current deployment configuration summary',
660
+ service,
661
+ source: 'kubernetes',
662
+ category: 'configuration',
663
+ evidence: [
664
+ 'Chart version: 2.4.1',
665
+ 'Replicas: 5/5 ready',
666
+ 'Last rollout: succeeded',
667
+ 'Image: registry.company.com/' + service + ':v1.42.0',
668
+ ],
669
+ suggestedAction: 'No action needed - deployment is healthy',
670
+ });
671
+ return findings;
672
+ }
673
+ /**
674
+ * Generate service dependency findings
675
+ */
676
+ function generateDependencyFindings(service, random) {
677
+ const findings = [];
678
+ // Define service dependency graph
679
+ const dependencyGraph = {
680
+ 'api-gateway': {
681
+ upstream: ['nginx', 'cloudflare'],
682
+ downstream: ['auth-service', 'user-service', 'order-service', 'payment-service'],
683
+ },
684
+ 'payment-service': {
685
+ upstream: ['api-gateway', 'order-service'],
686
+ downstream: ['stripe-api', 'postgres', 'kafka'],
687
+ },
688
+ 'auth-service': {
689
+ upstream: ['api-gateway'],
690
+ downstream: ['redis', 'postgres', 'okta-api'],
691
+ },
692
+ 'config-service': {
693
+ upstream: ['api-gateway'],
694
+ downstream: ['consul', 'vault'],
695
+ },
696
+ 'brokerage-service': {
697
+ upstream: ['api-gateway', 'trading-service'],
698
+ downstream: ['market-data-api', 'postgres', 'kafka'],
699
+ },
700
+ 'financing-service': {
701
+ upstream: ['api-gateway', 'portfolio-service'],
702
+ downstream: ['risk-engine', 'postgres', 'kafka'],
703
+ },
704
+ 'portfolio-service': {
705
+ upstream: ['api-gateway', 'trading-service'],
706
+ downstream: ['postgres', 'redis', 'kafka'],
707
+ },
708
+ };
709
+ const deps = dependencyGraph[service] || {
710
+ upstream: ['api-gateway'],
711
+ downstream: ['postgres', 'redis'],
712
+ };
713
+ findings.push({
714
+ priority: 'P3',
715
+ title: `Dependencies: ${service} dependency map`,
716
+ description: `${deps.upstream.length} upstream, ${deps.downstream.length} downstream dependencies`,
717
+ service,
718
+ source: 'service-mesh',
719
+ category: 'configuration',
720
+ evidence: [
721
+ `Upstream (calls ${service}): ${deps.upstream.join(', ')}`,
722
+ `Downstream (${service} calls): ${deps.downstream.join(', ')}`,
723
+ 'Source: Service mesh telemetry',
724
+ ],
725
+ suggestedAction: 'Check downstream services for cascading failures',
726
+ });
727
+ // Health status of dependencies
728
+ const unhealthyDep = deps.downstream[Math.floor(random.next() * deps.downstream.length)];
729
+ const isUnhealthy = random.next() > 0.6;
730
+ if (isUnhealthy) {
731
+ findings.push({
732
+ priority: 'P2',
733
+ title: `Dependencies: ${unhealthyDep} showing elevated latency`,
734
+ description: `Downstream dependency ${unhealthyDep} has p99 latency of 850ms (threshold: 500ms)`,
735
+ service: unhealthyDep,
736
+ source: 'service-mesh',
737
+ category: 'latency',
738
+ evidence: [
739
+ `Dependency: ${unhealthyDep}`,
740
+ 'P99 latency: 850ms',
741
+ 'Error rate: 0.5%',
742
+ `Impact: May affect ${service} response times`,
743
+ ],
744
+ suggestedAction: `Investigate ${unhealthyDep} as potential root cause`,
745
+ });
746
+ }
747
+ return findings;
748
+ }
578
749
  // Helper functions
579
750
  function determinePriority(message, random) {
580
751
  const msg = message.toLowerCase();