Skip to main content
This page explains the core concepts that power Limelight. Understanding these will help you get the most out of the MCP server and desktop app.

Debug IR

Debug IR (Debug Intermediate Representation) is the structured format Limelight uses to represent runtime analysis. Think of it like an AST for debugging — a machine-readable, token-efficient representation of what happened, why it happened, and what to do about it.

Why not raw logs?

Raw logs and network traces are noisy, unstructured, and expensive for AI to parse. A single debugging session might produce thousands of events. Dumping all of that into an LLM’s context window wastes tokens and produces worse results. Debug IR solves this by:
  1. Correlating raw events into causal chains before the AI sees them
  2. Detecting known anti-patterns automatically (so the AI doesn’t have to)
  3. Anonymizing sensitive values (passwords become [string, 12 chars])
  4. Structuring output as typed JSON with consistent schemas
  5. Ruling out non-causes (so the AI doesn’t chase false leads)

What’s in a Debug IR analysis

{
  "issue": "Search results showing stale data after typing",
  "causalChain": [
    { "event": "GET /api/search?q=re", "time": "0ms" },
    { "event": "GET /api/search?q=rea", "time": "50ms" },
    { "event": "Response for q=rea arrived", "time": "120ms" },
    { "event": "Response for q=re arrived (slower)", "time": "300ms" },
    { "event": "setState with stale q=re results", "time": "301ms" }
  ],
  "violations": [
    "Out-of-order response: q=re responded after q=rea",
    "Stale state overwrite: older results replaced newer results"
  ],
  "excludedCauses": [
    "Server error (both requests returned 200)",
    "Component unmount (SearchResults still mounted)"
  ],
  "suggestion": "Add AbortController to cancel superseded requests"
}
Every surface — MCP server, desktop app, future API — consumes the same Debug IR. The analysis runs once and is delivered everywhere.

Correlation Engine

The correlation engine is what transforms a flat list of runtime events into a connected graph of cause and effect.

How it works

When you ask Limelight to investigate an error or analyze a component, the correlation engine:
  1. Collects candidate events in a time window around the target
  2. Analyzes relationships between events using timing, trace IDs, component hierarchy, and state flow
  3. Scores each relationship with a confidence value
  4. Classifies edges by type:
Edge TypeMeaningExample
TRIGGEREDDirect causationNetwork response → setState
CONTRIBUTEDContributing factorSlow API → component timeout
FOLLOWEDTemporal sequence, likely relatedLogin → redirect → dashboard render
EVIDENCEContext for understandingConsole warning logged near the error
  1. Builds a correlation graph with the target event at the center and related events as nodes

What makes this different from DevTools

Browser DevTools shows you individual events in isolated panels — network tab, console tab, components tab. You mentally correlate them yourself. Limelight does this correlation automatically:
  • A failed network request is linked to the error log it produced, the state update it prevented, and the component that’s now showing stale data
  • A slow re-render is linked to the prop change that caused it, the state update that changed the prop, and the network response that triggered the state update

Causal Chains

A causal chain is an ordered sequence of events that explains how a problem occurred. It’s the core output of the Debug IR pipeline.

Example: “Why is checkout failing?”

1. User clicks "Place Order" → POST /api/orders fires
2. POST /api/orders returns 201 with order ID
3. GET /api/orders/{id}/status fires to poll order state
4. Payment webhook arrives at server, updates order to "paid"
5. GET /api/orders/{id}/status returns "pending" (race condition — polled before webhook)
6. Client sets orderStatus = "pending", shows "Payment processing..." indefinitely
The causal chain shows the exact sequence. The violation detection flags the race condition. The excluded causes section notes that the payment itself succeeded (ruling out payment gateway issues). This is the context an AI needs to suggest the right fix — not a retry, but a WebSocket subscription or longer polling interval.

How chains are built

  1. Start from the target event (the error, the slow render, the failed request)
  2. Walk backwards through the correlation graph following high-confidence edges
  3. Walk forwards to see the downstream effects
  4. Include only events that are causally relevant (not everything that happened to occur nearby)
  5. Order chronologically and annotate each step

Event Types

Limelight captures four types of runtime events:

Network Requests

Every fetch and XMLHttpRequest with full request/response data, timing, status, and automatic GraphQL detection. Failed requests (4xx, 5xx, network errors) are flagged automatically.

Console Logs

All console.log, .warn, .error, .info, and .debug calls with timestamps, source detection, and stack traces for errors.

Component Renders

React component render profiles captured from the Fiber tree — render count, cost (ms), velocity (renders/sec), cause breakdown (props vs state vs context vs parent), and changed props with reference stability analysis.

State Updates

Zustand and Redux store changes with action names, changed keys, and shallow diffs. State values are type-described by default for privacy.

Anti-Pattern Detection

The engine automatically detects these runtime anti-patterns:
Multiple identical or near-identical network requests fired in rapid succession. Common when a list component fetches data per item instead of batching.
A component re-rendering at unsustainable velocity — often caused by a state update inside a useEffect without proper dependencies.
Out-of-order responses where a slower request’s response overwrites the result of a faster, more recent request. Classic search-as-you-type bug.
Props that change reference on every render (inline objects, arrays, or callbacks) causing unnecessary child re-renders. Detected by comparing prop reference stability across renders.
A parent component re-render that triggers a deep chain of child re-renders. Often caused by context changes or lifting state too high.
Rapid repeated requests to the same endpoint, often caused by error handlers that retry without backoff.
Event handlers or callbacks that capture outdated state values. Detected when a handler references state that has since changed.
A circular dependency where a state update triggers a render, which triggers another state update. Critical severity — can crash the app.