@obsunified/collector 2.1.1 → 2.2.1

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 (37) hide show
  1. package/dist/{chunk-XKQTVIRE.js → chunk-ZSF5XP3B.js} +8 -2
  2. package/dist/chunk-ZSF5XP3B.js.map +1 -0
  3. package/dist/index.d.ts +359 -2
  4. package/dist/index.js +5000 -334
  5. package/dist/index.js.map +1 -1
  6. package/dist/{openai-FJYOQ7WO.js → openai-GSJZGFGL.js} +2 -2
  7. package/package.json +2 -2
  8. package/src/__tests__/autosre-closed-loop.test.ts +2222 -0
  9. package/src/index.ts +43 -0
  10. package/src/lib/analyses-runner.ts +46 -0
  11. package/src/lib/autosre-change-correlation.ts +807 -0
  12. package/src/lib/autosre-findings.ts +763 -0
  13. package/src/lib/autosre-ontology-cache.test.ts +78 -0
  14. package/src/lib/autosre-ontology.ts +938 -0
  15. package/src/lib/autosre-remediation-gate.ts +2127 -0
  16. package/src/lib/eval-cases-store.ts +63 -1
  17. package/src/lib/evidence-references.ts +6 -0
  18. package/src/lib/housekeeping.test.ts +150 -0
  19. package/src/lib/housekeeping.ts +109 -1
  20. package/src/lib/store/ingest.ts +46 -6
  21. package/src/migrations/050_autosre_causal_ontology.sql +216 -0
  22. package/src/migrations/051_incident_active_dedup_unique.sql +31 -0
  23. package/src/migrations/alert-state-notified.test.ts +3 -3
  24. package/src/migrations/parity.test.ts +4 -0
  25. package/src/migrations/project-scoped-keys.test.ts +1 -1
  26. package/src/migrations-postgres/050_autosre_causal_ontology.sql +216 -0
  27. package/src/migrations-postgres/051_incident_active_dedup_unique.sql +31 -0
  28. package/src/plugins/alerts-evaluator.ts +29 -1
  29. package/src/plugins/autosre-routes.ts +1134 -0
  30. package/src/plugins/connected-routes/manifest.ts +10 -1
  31. package/src/plugins/connected-routes.ts +241 -0
  32. package/src/plugins/default-span-enrichment.ts +13 -1
  33. package/src/plugins/eval-cases-routes.ts +57 -2
  34. package/src/plugins/evidence-retrieval-routes.test.ts +32 -0
  35. package/src/plugins/evidence-retrieval-routes.ts +643 -5
  36. package/dist/chunk-XKQTVIRE.js.map +0 -1
  37. /package/dist/{openai-FJYOQ7WO.js.map → openai-GSJZGFGL.js.map} +0 -0
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  import { alertsRoutesPlugin } from "./plugins/alerts-routes";
14
14
  import { analysesRoutesPlugin } from "./plugins/analyses-routes";
15
15
  import { askRoutesPlugin } from "./plugins/ask-routes";
16
+ import { autosreRoutesPlugin } from "./plugins/autosre-routes";
16
17
  import { botFilterPlugin } from "./plugins/bot-filter";
17
18
  import { connectedRoutesPlugin } from "./plugins/connected-routes";
18
19
  import { dashboardRoutesPlugin } from "./plugins/dashboard-routes";
@@ -91,6 +92,46 @@ export {
91
92
  type ToolCallRecord,
92
93
  } from "./lib/actions-store";
93
94
  export { AlertsStore, compareValue } from "./lib/alerts-store";
95
+ export {
96
+ computeChangeBlastRadius,
97
+ findCrossTraceContention,
98
+ getChangeEvent,
99
+ listChangeEvents,
100
+ recordChangeEvent,
101
+ } from "./lib/autosre-change-correlation";
102
+ export {
103
+ CounterfactualVerificationError,
104
+ getInvestigationFinding,
105
+ recordInvestigationFinding,
106
+ searchInvestigationFindings,
107
+ verifyPairedCounterfactualProof,
108
+ } from "./lib/autosre-findings";
109
+ export {
110
+ computeTarjanScc,
111
+ extractSpanLineageAndTopology,
112
+ getOntologyGraph,
113
+ loadTraceFaultLocusFromDb,
114
+ localizeTraceFaultLocus,
115
+ upsertOntologyFromSpans,
116
+ } from "./lib/autosre-ontology";
117
+ export {
118
+ acquireIncidentLease,
119
+ approveRemediationProposal,
120
+ claimRemediationGrant,
121
+ completeRemediationProposal,
122
+ dispatchIncidentWebhook,
123
+ evaluateRemediationWatchdogs,
124
+ failRemediationProposal,
125
+ getIncidentInvestigation,
126
+ getRemediationProposal,
127
+ listIncidentInvestigations,
128
+ listRemediationProposals,
129
+ openOrDeduplicateIncident,
130
+ proposeRemediationAction,
131
+ RemediationGateError,
132
+ rejectRemediationProposal,
133
+ type WatchdogEvaluationSummary,
134
+ } from "./lib/autosre-remediation-gate";
94
135
  export {
95
136
  type BlobListOptions,
96
137
  type BlobListResult,
@@ -134,6 +175,7 @@ export {
134
175
  alertsRoutesPlugin,
135
176
  analysesRoutesPlugin,
136
177
  askRoutesPlugin,
178
+ autosreRoutesPlugin,
137
179
  botFilterPlugin,
138
180
  connectedRoutesPlugin,
139
181
  createAlertEvaluatorHandler,
@@ -202,6 +244,7 @@ export const allPlugins = [
202
244
  analysesRoutesPlugin,
203
245
  actionRoutesPlugin,
204
246
  evalCasesRoutesPlugin,
247
+ autosreRoutesPlugin,
205
248
  evidenceRetrievalRoutesPlugin,
206
249
  askRoutesPlugin,
207
250
  tailRoutesPlugin,
@@ -36,6 +36,11 @@ import {
36
36
  type Logger,
37
37
  } from "../framework/logger";
38
38
  import { AnalysesStore } from "./analyses-store";
39
+ import {
40
+ evaluateRemediationWatchdogs,
41
+ openOrDeduplicateIncident,
42
+ resolveServiceIncidentTarget,
43
+ } from "./autosre-remediation-gate";
39
44
  import { generateNarrative, LlmCallError, type LlmConfig } from "./llm";
40
45
  import {
41
46
  computeSignature,
@@ -291,6 +296,20 @@ export async function runAllDueAnalyses(
291
296
  totals.narrated += summary.narrated;
292
297
  totals.skipped += summary.skipped ?? 0;
293
298
  }
299
+
300
+ // RFC 0013 § 5.B: the post-remediation watchdog (grant/claim timeouts and the
301
+ // +2m/+5m/+15m recovery checkpoints) rides the 1-minute tick so checkpoints
302
+ // are evaluated close to when they come due. Cross-project by design.
303
+ try {
304
+ const wd = await evaluateRemediationWatchdogs(db, { logger });
305
+ if (wd.evaluated + wd.timedOutClaims + wd.expiredGrants + wd.failed > 0) {
306
+ logger.info("[analyses] remediation watchdog summary", { ...wd });
307
+ }
308
+ } catch (error) {
309
+ logger.error("[analyses] remediation watchdog failed", {
310
+ error: error instanceof Error ? error.message : String(error),
311
+ });
312
+ }
294
313
  return totals;
295
314
  }
296
315
 
@@ -475,6 +494,33 @@ async function runDueAnalysesForProject(
475
494
  if (result.narrative) narrated += 1;
476
495
  }
477
496
  await store.insertResult(result, expiresAt);
497
+ if (result.status === "critical") {
498
+ try {
499
+ const scopeService = def.scope?.service;
500
+ const target = await resolveServiceIncidentTarget(
501
+ db,
502
+ projectId,
503
+ typeof scopeService === "string" ? scopeService : null,
504
+ `analysis:${def.id}`,
505
+ logger,
506
+ );
507
+ await openOrDeduplicateIncident(db, projectId, {
508
+ environment: target.environment,
509
+ targetNodeId: target.targetNodeId,
510
+ symptomAnchorKind: "analysis",
511
+ symptomAnchorId: def.id,
512
+ });
513
+ } catch (incidentError) {
514
+ // Incident bookkeeping must not fail the analysis run.
515
+ logger.error("[analyses] failed to open incident", {
516
+ analysis_id: def.id,
517
+ error:
518
+ incidentError instanceof Error
519
+ ? incidentError.message
520
+ : String(incidentError),
521
+ });
522
+ }
523
+ }
478
524
  // markRan releases the claim as a side-effect.
479
525
  await store.markRan(projectId, def.id, result.generatedAt);
480
526
  ran += 1;