From Noise to Narrative: How the RCA Engine Builds a Causal Story From Your Findings
The Root Cause Analysis engine reads every finding your scripts produce and stitches them into a single causal chain — root, contributing, symptom.
Every NOC has the same painful midnight pattern. An alert fires. Three more follow within seconds. A ticket gets opened, a bridge is started, twelve engineers join, and someone begins copy-pasting CLI output into a chat window. An hour later the team agrees on a root cause — usually one that another engineer flagged in a finding three days earlier. The data was there. The story was not.
The Root Cause Analysis (RCA) engine exists to write that story for you. It pulls every finding produced by your diagnostic scripts in a configurable window, hands them to a large reasoning model, and returns a structured causal chain you can read in seconds.
What a finding actually is
A finding is the atomic unit of evidence in the platform. Whenever you run a script through the Streaming Console, custom parsers emit findings into netops_findings. Each finding carries a severity, category, device, signal name, message, and — crucially — a correlation key. The correlation key is what makes RCA possible. Two findings with the same key (for example bgp/peer-down/10.0.0.1) are two observations of the same underlying phenomenon, even if they were emitted by different scripts on different devices.
The correlation pipeline
When you click Run RCA, the panel calls the correlateFindings server function. That function does four things, in order:
- Scopes findings to the active workspace and project so you never leak data across tenants.
- Pulls the most recent N findings from the chosen window (default 24h, max 168h).
- Compacts each finding into a tight JSON record — severity, category, device, signal, message, key, time.
- Sends the compacted batch to Gemini 2.5 Pro through the Lovable AI Gateway with a strict output schema.
The schema (RcaChainSchema) forces the model to return nodes typed as root, contributing, or symptom, plus directed edges. That structure is what lets the panel render a graph instead of a wall of text.
Why a typed schema matters
A free-form summary from the model would feel impressive in a demo and useless in production. You cannot group, link, or audit prose. The typed chain lets us colour root nodes red, attach evidence counts, link symptoms back to specific runs, and — eventually — replay the same chain six months later when the issue recurs.
What the chain tells you
A good chain answers three questions in one diagram. What broke? The root nodes. What made it worse or louder? The contributing nodes. What did your monitoring actually see? The symptom nodes. The recommendations array — also schema-enforced — gives you the next three concrete actions, ordered by impact.
Confidence is a first-class field
Every chain ships with a confidence score. Low confidence usually means one of three things: the window was too short, findings came from too few devices, or the correlation keys are not granular enough. The panel surfaces this honestly so an SRE can decide whether to widen the window, run more diagnostics, or escalate.
Working backwards from the chain
Each node in the rendered ChainGraph is clickable and expands to show the underlying findings. From there you can jump to the originating run in the Streaming Console, re-execute the diagnostic against a new device, or push the recommendation into a runbook. The chain is the entry point — not the endpoint — of the investigation.
Designing scripts for great RCA
The quality of the chain is bounded by the quality of your findings. Three habits dramatically improve results:
- Pick stable correlation keys. A key like
interface/flap/Gi0/0is far more useful thanflap-12345. Stability across runs is what lets the model count repetition. - Keep messages short and factual. The model handles tens of findings at once; verbose messages eat context for no benefit. Save the long explanation for the script's full output.
- Use severity honestly. If everything is critical, nothing is. The model uses severity to decide which nodes deserve to be roots.
Privacy and tenancy
RCA never reads across users. The auth middleware injects the caller's Supabase client, so all queries are scoped by RLS. When a project filter is active, the function additionally constrains findings to runs that belong to that project. The model only ever sees what the calling user could see in the UI.
Cost and latency
A typical 24-hour window with 60 findings completes in roughly four to seven seconds. The function caps the batch at 200 findings to keep token use bounded; widening the window beyond that mostly hurts signal anyway. If your environment is genuinely producing 500 findings an hour, that is a separate conversation about script noise, not about RCA.
What to do next
Open the Intelligence tab, pick a window that covers a recent incident, and run RCA. Compare the chain to your post-mortem document — the gap between the two is exactly the muscle this engine is meant to replace.
Was this helpful?
Generate scripts for the task covered in this post
Describe what you need and NAPT writes production-ready automation in Netmiko, NAPALM, or Nornir.
Open Script Generator →Related posts
The Streaming Console: A Live Terminal That Remembers Everything
Run any diagnostic script against any device, watch output stream in real time, and end up with structured findings the platform can reason about.
Read →Intent: Saying What You Mean and Proving the Network Agrees
Write a one-line statement of how the network should behave. The Intent engine compiles it into checks and tells you where reality diverges.
Read →Drift: Knowing Exactly What Changed, On Which Device, and When
Drift watches your device configs, diffs them against a baseline with grouping-aware rules, and tells the story of every change without the noise.
Read →