Reliability Analytics & Self-Serve Tooling
Regression detection at scale and the data tooling that makes engineers self-sufficient
Regression detection frameworks
After this you can design a system that catches regressions before users do
The reliability mandate at Cursor lives or dies on one question: do you find a regression from a screenshot a user posts or from your own alert that fired twenty minutes after the deploy? This section is about building the second world.
A detection framework has two halves that get confused in interviews. Pre-deploy catches the regression before it reaches everyone, on a slice of traffic you control. Post-deploy catches what slipped through, on the live time series of latency, error rate and agent success. You need both, because a canary that sees 1% of traffic for ten minutes cannot surface a regression that only bites the long tail of a particular model on a particular client.
The two layers and what each one is forpre-deploy vs post-deploy
- Layer
- Pre-deploy
- Method
- A/A baseline + canary on a traffic slice
- Catches
- Gross regressions before full rollout
- Blind spot
- Rare slices, slow-burn effects, novelty
- Layer
- Post-deploy
- Method
- Change-point detection on the live series
- Catches
- What the canary's sample missed
- Blind spot
- Lag - users may feel it before the point shifts
- Layer
- Continuous
- Method
- Anomaly detection per segment
- Catches
- Drifts with no deploy (a provider degrades)
- Blind spot
- Alert fatigue if thresholds are naive
| Layer | Method | Catches | Blind spot |
|---|---|---|---|
| Pre-deploy | A/A baseline + canary on a traffic slice | Gross regressions before full rollout | Rare slices, slow-burn effects, novelty |
| Post-deploy | Change-point detection on the live series | What the canary's sample missed | Lag - users may feel it before the point shifts |
| Continuous | Anomaly detection per segment | Drifts with no deploy (a provider degrades) | Alert fatigue if thresholds are naive |
Defense in depth: each layer covers a failure the others structurally cannot see.
Start a canary by proving your measurement is trustworthy. An A/A test routes two arms to identical code and confirms the metric shows no difference. If your A/A flags a phantom regression, your detector is miscalibrated and every real alert is suspect.
- 1A/A baseline. Split identical traffic two ways; confirm the latency and success deltas sit inside noise. This calibrates the false-positive rate you'll live with.
- 2Canary the change. Route a small, representative slice to the new build. Representative matters more than large: cover the models, regions and clients that dominate volume.
- 3Compare on guardrails. Watch p95/p99 latency, error rate, timeout rate and agent success on the canary versus control, not just the average.
- 4Promote or roll back. Gate the full rollout on the canary clearing its thresholds. A failed canary is a non-event for users, which is the whole point.
- 5Watch the live series. Once promoted, change-point detection takes over on the full population to catch what 1% couldn't.
Interactive diagram. Tab through its regions; each focused region shows its detail in the panel below.
Each step earns the next. The gate is the promotion decision - a failed canary is a non-event for users, which is the whole point.
Change-point detection over static thresholds
A fixed threshold like "alert if p95 > 4s" breaks both ways: it's deaf to a regression that moves p95 from 800ms to 1.6s and it screams every time legitimate traffic shifts. Change-point detection asks a better question - did the distribution's behavior shift at some point in time, relative to its own recent history?
"Alert if error rate > 1%."
Misses a 0.2% → 0.6% tripling that's plainly a regression.
Needs constant hand-tuning per metric and segment.
"Alert when the series departs its own recent baseline."
Catches relative shifts at any absolute level.
Adapts as baselines drift with traffic and seasonality.
Sensitivity vs alert fatigue
Every detector has a knob between catching real regressions and crying wolf. Tie that knob to economics, not vibes. The cost of a missed regression is its blast radiusHow much breaks if a change goes wrong; the scope of potential damage. in frustrated users; the cost of a false positive is an engineer's interrupted afternoon and slow erosion of trust in the alert. Calibrate against your error budget: page when burn rate threatens the SLO, file a ticket when it merely nicks it.
- Page (wake someone)
- Fast burn of the error budget; user-visible and spreading
- Ticket (next business day)
- Slow burn; real but bounded, no spreading
- Dashboard only
- Inside noise or within budget; watch, don't interrupt
- Suppress
- Known maintenance window or expected deploy blip
The threshold is a business decision about false-positive cost, dressed up as statistics.
Segment-aware alerting
The global line is a liar. A regression that doubles latency for one model in one region can be completely invisible in the aggregate, because that slice is a small share of total volume. At Cursor's scale the unit of analysis is the user-AI interaction across billions per period and the regressions that matter most often hide in a single dimension.
- Cut every reliability metric by model, region, client version and surface (Tab, Agent, chat) before you trust the headline number.
- A flat global p95 with a spiking per-model p95 is the classic Simpson's-paradox trap - the mix moved, not the experience.
- Run detection per segment, not only on the rollup or you'll ship the regression that only hurts the new client build.
Make it actionable, then auto-triage
A detected regression that says "latency is up" wastes the on-call's first hour. Stamp every interaction with a release/commit/model-version dimension at log time so a change-point can name its likely cause: this regression starts at deploy abc123, on model X. That single join turns an observation into an assignment.
The hardest, most Cursor-specific triage is separating a model regression from a harness regression. The model got worse versus your agent loop, tool-calls or context assembly got worse. Route them to different owners and route fast.
- Symptom pattern
- Quality drop tracks a model-version flip, harness unchanged
- Likely culprit
- Model regression
- Route to
- Model/eval team
- Symptom pattern
- Tool-call failure or timeout rate jumps after a deploy
- Likely culprit
- Harness regression
- Route to
- Agent-harness eng
- Symptom pattern
- Latency up only on one provider/region
- Likely culprit
- Upstream/infra
- Route to
- Infra / provider on-call
- Symptom pattern
- Success down across all models at once
- Likely culprit
- Shared harness or context layer
- Route to
- Harness eng
| Symptom pattern | Likely culprit | Route to |
|---|---|---|
| Quality drop tracks a model-version flip, harness unchanged | Model regression | Model/eval team |
| Tool-call failure or timeout rate jumps after a deploy | Harness regression | Agent-harness eng |
| Latency up only on one provider/region | Upstream/infra | Infra / provider on-call |
| Success down across all models at once | Shared harness or context layer | Harness eng |
Auto-triage is a routing table over the dimensions you logged - design those dimensions on purpose.
When they hand you "latency went up, how do you investigate," do not start guessing causes. Say you'd first confirm the signal is real (is the A/A clean, is it one segment or all), then localize it on the dimensions you log (deploy, model, region, client), then classify model-vs-harness, then quantify blast radiusHow much breaks if a change goes wrong; the scope of potential damage. before paging anyone. Naming that order is what reads as someone who has owned detection, not just plotted a metric.
Don't promise a detector with zero false positives - that just means it's deaf to real regressions. The honest framing is that you pick a point on the sensitivity curve deliberately, justify it with the false-positive cost and the error budget and revisit it as the org's tolerance changes.
Takeaway. Catch regressions in layers: A/A-calibrated canaries pre-deploy, change-point detection on the live series post-deploy, all run per segment and stamped with deploy/model/region so an alert names its cause and auto-triages model-vs-harness instead of just saying "latency is up."
Self-check
QYour global p95 latency is flat after a deploy, but support reports slowness. What's the most likely measurement failure and what do you check first?
Working with heavy-tailed telemetry
After this you can do statistically honest analysis on messy logs
Latency logs are not a tidy bell curve you can summarize with a mean and a standard deviation. They are heavy-tailed, multimodal, censored and polluted - and the candidate who averages them away will get caught in the technical screen.
A request that hits a warm cache returns in 40ms; the same request on a cold start with a slow tool-call takes 8 seconds. That's two populations in one column. The mean lands in the empty valley between them, describing no real request. Model the shape before you summarize it.
Why the mean lies hereshape before summary
A few very slow requests drag the mean far above the typical experience.
p99 can be 20x the median - and the tail is what users complain about.
Cache hit vs miss, cold start vs warm, short vs long agent turn.
One average smears distinct regimes into a number nobody experiences.
In-flight and aborted runs have no final latency yet.
Dropping them biases you fast; the slow ones are exactly the censored ones.
Robust statistics, not parametric defaults
Reach for estimators that survive ugly distributions. Percentiles describe the experience directly: p50 is the typical request, p95/p99 are the tail you're paid to protect. When you need a center of mass, a trimmed mean or median beats the raw mean. For spread, MAD (median absolute deviation) shrugs off outliers that would blow up a standard deviation.
- Question
- Typical latency?
- Naive tool
- Mean
- Robust tool
- Median (p50)
- Question
- Tail experience?
- Naive tool
- Max
- Robust tool
- p95 / p99 (and watch p99.9)
- Question
- Spread?
- Naive tool
- Std dev
- Robust tool
- MAD or IQR
- Question
- Confidence interval on a skewed metric?
- Naive tool
- t-interval
- Robust tool
- Bootstrap
- Question
- Center when outliers present?
- Naive tool
- Mean
- Robust tool
- Trimmed mean
| Question | Naive tool | Robust tool |
|---|---|---|
| Typical latency? | Mean | Median (p50) |
| Tail experience? | Max | p95 / p99 (and watch p99.9) |
| Spread? | Std dev | MAD or IQR |
| Confidence interval on a skewed metric? | t-interval | Bootstrap |
| Center when outliers present? | Mean | Trimmed mean |
Heavy-tailed data punishes parametric defaults; robust estimators are the honest answer.
When a distribution is too gnarly for a closed-form interval, bootstrap it. Resample the data with replacement thousands of times, recompute your statistic each time and read the confidence interval off the resampled distribution. It makes no normality assumption, which is exactly why it fits latency and success-rate work.
import numpy as np
def bootstrap_p95(latencies, n_boot=10_000, alpha=0.05):
x = np.asarray(latencies, dtype=float)
boot = np.empty(n_boot)
for i in range(n_boot):
sample = np.random.choice(x, size=x.size, replace=True)
boot[i] = np.percentile(sample, 95)
lo, hi = np.percentile(boot, [100 * alpha / 2, 100 * (1 - alpha / 2)])
return float(np.percentile(x, 95)), (float(lo), float(hi))
# p95 with a 95% CI you can defend on skewed dataDe-noise before you count
Raw logs over-count failures and under-count truth. Three retries of one user action look like three failures and one success unless you collapse them. Client clock skew makes some latencies negative. Bot and automation traffic has a different distribution than humans. An instrumentation bug can manufacture a regression that never touched a user.
- 1Sessionize. Group events into logical attempts so one user action is one row, not one row per retry.
- 2Dedup retries and timeouts. Collapse a retry chain into a single attempt with a final outcome before you compute failure rate.
- 3Filter non-human traffic. Segment out bots and automation or at least tag them so they never silently inflate a metric.
- 4Sanity-check the clock. Drop or correct negative and absurd durations from client skew before they poison percentiles.
- 5Audit the instrument. When a metric jumps, rule out an instrumentation or schema change before declaring a real regression.
Counting raw log lines answers "how many requests failed." Counting sessionized attempts answers "how many user actions failed," which is what reliability actually means. The two can disagree by a wide margin precisely when retries spike - exactly the moment you most need the right number.
Censoring and survivorship
An aborted or still-running agent turn is right-censored: you know it took at least this long, not how long it finally took. Treating it as a completed fast request or dropping it, both bias you toward looking healthier than you are. Survivorship bias is the same trap from the other side: if only successful runs reach the table you analyze, your success rate is a tautology.
Don't compute success rate over only the runs that produced a final event. The runs that hung, timed out or were killed are the failures you care about and they're the ones most likely to be missing from a naive table. Always reconcile your denominator against admitted attempts, not completed ones.
Takeaway. Latency telemetry is heavy-tailed, multimodal and censored - describe it with percentiles, trimmed means, MAD and bootstrapped CIs, sessionize and dedup retries before counting failures and handle right-censored runs so your success rate isn't a survivorship tautology.
Self-check
SQL & Python craft for scale
After this you can demonstrate the hands-on data skills the screen tests
The technical screen for this role is data-shaped, not algorithmic: SQL on event/interaction data plus applied stats. They're checking whether you can actually pull p95 latency by model from a billion-row table without melting the warehouse - and whether someone could rerun your number tomorrow.
Three skills carry most screens. Window functions for sessionization and funnels, percentile aggregations for latency and cost-aware querying so your scan touches partitions instead of the whole table. Show all three on one realistic problem and you've answered the round.
Window functions and percentiles in angerthe moves they probe
WITH events AS (
SELECT user_id, model, run_id, event_ts, latency_ms, outcome
FROM agent_interactions
WHERE event_ts >= CURRENT_DATE - INTERVAL '7' DAY -- partition prune
AND surface = 'agent'
),
latency_by_model AS (
SELECT
model,
APPROX_PERCENTILE(latency_ms, 0.50) AS p50,
APPROX_PERCENTILE(latency_ms, 0.95) AS p95,
APPROX_PERCENTILE(latency_ms, 0.99) AS p99,
AVG(CASE WHEN outcome = 'success' THEN 1.0 ELSE 0.0 END) AS success_rate,
COUNT(*) AS n
FROM events
GROUP BY model
)
SELECT * FROM latency_by_model
WHERE n >= 1000 -- ignore segments too small to trust
ORDER BY p95 DESC;Two craft signals are hiding in that query. The date filter on a partitioned column prunes the scan instead of reading every row. And APPROX_PERCENTILE (or percentile_cont where exactness is needed) computes the tail at scale where an exact sort would be prohibitive - naming the exact-vs-approximate tradeoff out loud is a senior tell.
Cost-aware querying on billions of rows
- Technique
- Partition pruning
- What it buys
- Scan days, not years
- When to reach for it
- Always - filter on the partition key first
- Technique
- Pre-aggregation / rollups
- What it buys
- Dashboards read a small table
- When to reach for it
- Repeated, well-known reliability questions
- Technique
- Sampling
- What it buys
- Fast exploratory answers
- When to reach for it
- Iterating on a hypothesis, not a final number
- Technique
- Approximate quantiles
- What it buys
- Tail metrics at scale
- When to reach for it
- p95/p99 over huge groups
- Technique
- Column pruning
- What it buys
- Less I/O on wide event tables
- When to reach for it
- Select only the columns you need
| Technique | What it buys | When to reach for it |
|---|---|---|
| Partition pruning | Scan days, not years | Always - filter on the partition key first |
| Pre-aggregation / rollups | Dashboards read a small table | Repeated, well-known reliability questions |
| Sampling | Fast exploratory answers | Iterating on a hypothesis, not a final number |
| Approximate quantiles | Tail metrics at scale | p95/p99 over huge groups |
| Column pruning | Less I/O on wide event tables | Select only the columns you need |
On billions of rows, the query plan is part of the analysis - a correct number you can't afford is not an answer.
Python for log analysis and detection
SQL gets you aggregates; Python gets you the modeling SQL can't express. Pull a manageable slice with pandas or polars, run hypothesis tests with scipy/statsmodels and prototype lightweight detection - a change-point or anomaly check - before anyone builds the production version.
from statsmodels.stats.proportion import proportions_ztest
# successes / totals for control (pre) and treatment (post)
successes = [pre_success, post_success]
totals = [pre_total, post_total]
stat, pval = proportions_ztest(count=successes, nobs=totals)
delta = post_success / post_total - pre_success / pre_total
print(f"success-rate delta={delta:+.3%} p={pval:.4f}")
# A real regression should clear significance AND be large enough to matterAt billions of interactions, a 0.01% change is statistically significant and operationally meaningless. Always pair the p-value with the effect size and a materiality bar (does this move the error budget, does it affect a meaningful number of users). Reporting significance alone in this role reads as junior.
Driving Cursor through the analysis itselfthe analyst's own loop
This is also the work you'll do inside Cursor day to day, and it pays to set the workspace up like the team does. Cursor ships role-specific cookbooks - workflow recipes for different jobs - and the data science one is the place to start. It walks through Jupyter notebook development, wiring up database frameworks like Supabase and Postgres and the in-editor extensions for Postgres, BigQuery, SQLite and Snowflake so your warehouse lives next to your analysis.
Cursor has a number of different cookbooks - basically workflows for different types of roles. The data science one is honestly just a good place to start if you're figuring out how to incorporate Cursor inside your data science workflows.
For notebooks, install the Jupyter extensions from the same marketplace VS Code uses - check the publisher (the ones by MS Tools AI) and the download count before you trust one. One honest caveat from the field: Cursor can't always run Jupyter cells for you automatically, so expect to execute some cells by hand. The flip side is that Python frustrations are where the agent shines. Because Python is so heavily represented in training data, models are strong at the pip-version-venv mess - one recurring fix is pandas import could not be resolved because the package sat in system Python but not in the venv the notebook was using, which Cursor will diagnose, install into the venv and self-verify.
When Cursor offers to install into a virtualenv versus the project, pick the venv. It keeps the notebook's environment pinned and isolated, which is the same reproducibility discipline you'll demand of any number you ship - the slow-burn cousin of parameterizing your queries.
Model economics: plan with the smart model, build with the cheap one
The single rule of thumb worth stealing from the team: don't reach for the most expensive reasoning model by reflex. Start with the cheaper, standard model - the in-house ComposerCursor's own fast coding model, tuned for the editor and priced well below frontier models; the recommended day-to-day model for executing a plan. models are fast and genuinely underestimated - and only escalate to a frontier reasoning model (GPT-5.x, Opus 4.x) when the cheap one stalls. The exception is when a task obviously needs reasoning: building a plan, or a thorny bug where the model has to reason about where the problem even lives. Skip straight to the strong model there.
Use a high-reasoning model to work with Cursor on the plan, then switch to a simpler, cheaper, faster model for implementation - the heavy lifting is already in the plan. Using the most expensive model to build out the plan is like taking a Lamborghini to the grocery store. It's nice and it's cool, but it's expensive.
When you batch out work - say, generating a wall of charts from a cleaned export - reach for sub-agents. They're "baby Cursors": smaller agents with a clear persona and instructions, running inside a bigger agent, spun up from a create sub agent skill (roughly a 150-line Markdown persona). The Cursor-specific lever is that you set a model per sub-agentA child agent a main agent spawns to work in parallel with its own context window, handing results back so the parent's context stays clean., so a chart-builder doesn't need a frontier model racking up a bill - one of the in-house ComposerCursor's own fast coding model, tuned for the editor and priced well below frontier models; the recommended day-to-day model for executing a plan. models or a mid-tier model is plenty. You can launch several in parallel ("launch three chart-builder sub-agents" spins up three side-by-side workers, each visible in the sub-agent UI). One hard constraint: sub-agents need a reasoning model to drive them - the fastest execution-only Composer variant can't run sub-agents, so point them at a reasoning model.
Interactive widget. Tab through its controls; the result updates in the panel below as you change them.
Plan with a thinker, execute with a fast model.
Plan and locate hard bugs with a reasoning model; implement and batch-build with the cheap, fast in-house models. Auto routes when you'd rather not decide.
Reproducibility and data quality
An analysis an engineer can't rerun is a rumor. Parameterize your queries, keep the analysis under version control and make the result regenerate from inputs on demand. Then bake data-quality checks into the pipeline itself so a broken metric fails loudly instead of lying quietly.
- Parameterize date ranges, segments and thresholds - no magic numbers buried in SQL.
- Version-control the analysis so the number has provenance and a diff.
- Assert null, duplicate and skew checks in-pipeline; a metric that silently drops 30% of rows is worse than no metric.
- Pin the query and inputs so "rerun it next month" gives the same shape of answer, not a surprise.
In a SQL screen, narrate your cost reasoning before you optimize syntax. Say "I'll filter the partition key first so this scans a week, not the full history and use approximate percentiles since exact sort is overkill for a p95." Interviewers for an at-scale role weight that judgment as heavily as a correct join.
Takeaway. The screen rewards SQL that prunes partitions and uses approximate percentiles to get p50/p95/p99 by segment at scale, paired with Python that tests for significance AND materiality - and every number must be parameterized, version-controlled and rerunnable with data-quality checks baked in.
Self-check
QYou need p99 latency by model over the last 90 days from a 5-billion-row partitioned event table. Which approach best balances correctness and cost?
Building self-serve data tooling
After this you can design analytics tooling for non-data users
The JD is explicit: you build data tooling that lets engineers answer their own questions, instead of routing every reliability query through you. The win condition is fewer ad-hoc asks, not more dashboards.
This is the difference between a data scientist who gatekeeps and one who scales the org. Cursor wants the second kind. The core artifact is a metric layer that makes "agent success rate" mean one thing everywhere, plus interfaces an engineer can drive without a DS in the loop.
Interactive diagram. Tab through its regions; each focused region shows its detail in the panel below.
Each layer rests on the one below - no clever dashboard recovers a dimension the instrumentation never logged.
The semantic / metric layerdefine once, agree everywhere
Without a metric layer, every team writes its own SQL for "success rate," and three dashboards disagree by lunch. A semantic layer defines each metric once - the exact filter, the denominator, the sessionization - so every dashboard, alert and query resolves to the same definition. It kills the "whose number is right" debate that quietly drains trust.
metric: agent_success_rate description: Share of admitted agent runs that reach a success outcome source: agent_interactions entity: run_id # sessionized: one row per logical attempt filter: surface = 'agent' AND is_bot = false numerator: count(run_id) where outcome = 'success' denominator: count(run_id) # admitted attempts, includes censored = failure dimensions: [model, region, client_version, surface] owner: reliability-ds
Dashboards and query interfaces engineers actually use
"Is my deploy regressing latency?" as a one-click view scoped to a commit.
"Success rate by model this week" without writing SQL.
Pre-built so the 80% of asks never reach you.
Every headline metric drills into model/region/client segments.
An engineer can localize a regression themselves.
Links straight to the deploy dimension for triage.
For the one-off end of the spectrum - a finding you want to see right now, not maintain - Canvas is the fast path. Cursor writes React to render a dashboard directly inside the IDE, so an anonymized CSV usage export becomes a live, clickable dashboard you iterate on by talking to it ("match the Cursor dashboard", "add a tooltip"). It takes an image, a CSV or the codebase as input. The decision rule keeps it from becoming shadow tooling: Canvas is for one-off visualization and sharing. If you want an always-on dashboard, have Cursor build a real website - a small Next.js app - and deploy it, so it joins the self-serve stack instead of living in someone's editor.
Canvas renders a dashboard in seconds, which is exactly why it tempts people into making it load-bearing. A dashboard the whole team relies on belongs in a deployed app behind the semantic layer, not in a Canvas view one person can edit. Use Canvas to explore and share a finding; promote anything durable to real tooling.
Instrumentation and event-schema design upstream
You don't only analyze what's logged - you shape what gets logged. If the event schema doesn't carry model version, deploy id and a stable run id, no downstream cleverness recovers them. Designing instrumentation is the most impactful tooling work, because a missing field is a regression you can never attribute.
- Insist on a stable run_id and event ordering so sessionization is possible at all.
- Carry the triage dimensions (model version, deploy/commit, region, client version, surface) on the events themselves.
- Log the censoring signal - start, heartbeat, terminal - so aborted runs are distinguishable from fast ones.
- Treat schema as an interface: changes are versioned and announced, not silent.
Data observability so trust doesn't erode silently
A self-serve metric is only as trusted as its freshness. If the pipeline stalls and a dashboard quietly shows yesterday's data as today's, engineers will make a bad call and then stop trusting every dashboard. Observability on the data itself is what keeps the tooling credible.
- Signal
- Freshness
- What it catches
- Pipeline stalled, stale numbers
- Failure if missing
- Decisions made on yesterday's data
- Signal
- Volume
- What it catches
- Row counts dropped or doubled
- Failure if missing
- A drop reads as a fake regression
- Signal
- Schema change
- What it catches
- A field renamed or nulled upstream
- Failure if missing
- Metric silently breaks, no error
- Signal
- Distribution drift
- What it catches
- A column's shape shifted unexpectedly
- Failure if missing
- Real regression hides in a broken input
| Signal | What it catches | Failure if missing |
|---|---|---|
| Freshness | Pipeline stalled, stale numbers | Decisions made on yesterday's data |
| Volume | Row counts dropped or doubled | A drop reads as a fake regression |
| Schema change | A field renamed or nulled upstream | Metric silently breaks, no error |
| Distribution drift | A column's shape shifted unexpectedly | Real regression hides in a broken input |
Trust is the product here; observability alerts are how you protect it.
Measure your tooling by adoption and offload, not by how many dashboards exist. The signals: engineers answering their own reliability questions, ad-hoc asks routed to you trending down and teams aligning on the same metric definition in their own docs. Dashboards nobody opens are not a win.
"I'd land a metric layer first so success rate means one thing across every team, then ship templated drill-down views for the top reliability questions and instrument the event schema with the dimensions triage needs. I'd judge it by ad-hoc asks dropping and engineers self-serving, with data-observability alerts so a stale pipeline never silently misleads a decision."
Takeaway. Self-serve tooling means a semantic layer that defines each metric once, templated drill-down dashboards engineers drive without you, instrumentation you design upstream and data-observability alerts - judged by ad-hoc asks dropping, not by dashboard count.
Self-check
QTwo teams report different numbers for "agent success rate" and both are convinced theirs is correct. What's the structural fix and why is it tooling rather than a one-off reconciliation?
From signal to decision
After this you can connect analytics output to action, fast
Detection and clean stats are worth nothing if the finding sits in a notebook while users churn. Cursor runs at high pace, so the last mile - turning a signal into a decision someone acts on today - is where this role earns its seat.
Package findings for people who will read three sentences. Lead with the decision and the recommended action, state your confidence, then put the evidence underneath for whoever wants to verify. The inverted pyramid beats the academic build-up in a fast org.
- Decision
- What should happen - roll back deploy abc123
- Confidence
- How sure - clean signal in two segments, A/A clean
- Action + owner
- Who does what by when
- Evidence
- The charts and query, last, for verifiers
Decision first, evidence last - the opposite of how you discovered it.
Quantify blast radius to prioritize
When two regressions compete for one engineer's day, blast radiusHow much breaks if a change goes wrong; the scope of potential damage. decides. Affected users times severity gives a comparable number, so a 0.3% latency bump on the most-used surface can outrank a hard failure that hits a handful of people. Prioritizing by blast radius is how you focus a small team on the frustration that actually dominates.
Interactive diagram. Tab through its regions; each focused region shows its detail in the panel below.
Reach x severity, not loudness - the top-right corner is the incident, the rest get filed with evidence attached.
- Issue
- Tab latency +400ms
- Affected interactions
- Very high (most-used surface)
- Severity
- Moderate
- Blast radius → priority
- High - broad daily friction
- Issue
- Agent tool-call fails
- Affected interactions
- Low (one tool, one client)
- Severity
- High
- Blast radius → priority
- Medium - severe but narrow
- Issue
- Chat cosmetic glitch
- Affected interactions
- Medium
- Severity
- Low
- Blast radius → priority
- Low - annoying, not blocking
| Issue | Affected interactions | Severity | Blast radius → priority |
|---|---|---|---|
| Tab latency +400ms | Very high (most-used surface) | Moderate | High - broad daily friction |
| Agent tool-call fails | Low (one tool, one client) | High | Medium - severe but narrow |
| Chat cosmetic glitch | Medium | Low | Low - annoying, not blocking |
Reach x severity, not loudness, sets the queue - the squeaky bug isn't always the biggest one.
Escalate vs file - calibrate to impact
Fast error-budget burn, spreading, user-visible now.
Page the owner; the cost of waiting exceeds the cost of interrupting.
Real but bounded; not spreading; within budget.
Attach the evidence and blast-radius estimate so it's triaged on merit.
Close the loop and write the narrative
A fix is not done when it ships; it's done when the metric confirms the regression resolved. Verify in the same series you detected it, on the same segments and watch for the regression hiding in one slice while the global line recovers. Then write the postmortem-grade narrative so the next person inherits the lesson, not just the patch.
- 1Verify the fix. Confirm the metric returned to baseline in the affected segments, not just globally.
- 2Check for displacement. Make sure you fixed the regression rather than moving it to another slice.
- 3Quantify recovery. Restate blast radiusHow much breaks if a change goes wrong; the scope of potential damage. post-fix so the win is measured, not assumed.
- 4Write it up. What broke, how it was detected, root cause and the prevention that stops a repeat.
- What broke
- The user-visible symptom and the metric that moved
- How detected
- Which detector fired and how fast - or why it didn't
- Root cause
- Model vs harness vs infra, named on the dimension you logged
- Prevention
- The canary, alert or schema change that catches it next time
The prevention line is the one that compounds - it turns one incident into a permanent detector.
In the behavioral and hiring-manager rounds, tell a regression story end to end: how you detected it, how you quantified blast radiusHow much breaks if a change goes wrong; the scope of potential damage. to justify the priority, how you drove the decision and how you verified the fix and prevented a repeat. Cursor screens hard for truth-seeking and bias-to-ship - a story that ends at "I found it" reads as analysis; a story that ends at "and here's the detector that now catches it" reads as ownership.
Don't over-escalate. Paging the team for every blip burns trust and the same alert fatigue you fight in detection. Calibrate to real user impact and reserve the incident path for fast, spreading, budget-burning regressions - file the rest with evidence attached.
Takeaway. Package findings decision-first with confidence and a recommended action, prioritize by blast radiusHow much breaks if a change goes wrong; the scope of potential damage. (reach x severity), calibrate escalate-vs-file to user impact, then close the loop by verifying the fix in the affected segments and writing a postmortem whose prevention line becomes a permanent detector.