luciq-debug
The luciq-debug skill investigates a crash, hang, bug, or APM issue end to end, mapping Luciq data to your repo and proposing a cited fix.
Investigate a Luciq production signal end to end — crash, hang, user-reported bug, or APM performance issue — using the Luciq MCP server for context and the user's local repository for the code mapping. Form a hypothesis, propose a fix, cite the evidence.
Use this skill when
The user describes a crash, hang, or bug. "Why is this happening", "investigate this", "what broke".
The user pastes a stack trace, exception, or fingerprint and asks for a diagnosis.
The user references a specific Luciq crash ID, bug ID, or hang ID.
The user asks "what's regressing in version X" or "compare crashes between versions".
The user flags an APM performance issue: a slow endpoint, a latency or p95 spike, an apdex drop, a network failure-rate spike, slow app launch, UI jank (frozen or slow frames), slow screen loading, user-flow drop-off, a throughput change, or "what got slower or flakier since version X".
What the agent learns
luciq-debug turns the agent into an evidence-based debugger across crash, hang, bug, and APM signals:
Signal-typed methodology. Different decision trees for crashes, hangs, bug reports, and APM signals, each weighted by the evidence that matters for that signal.
MCP tool sequencing. Which Luciq MCP tool to call when, in the right order, with the right filters, without over-fetching.
APM coverage across all five metrics. Network endpoints, app launch, user flows, screen loading, and frame drop — the agent knows how to enter each signal, which APM views to pull, and how to localize a regression to a cohort or span.
Metric reference material. Before quoting an APM number, the agent reads that metric's reference files, covering units, coverage and account gating, stage boundaries, and the conditions that make a number misleading. Populated for network and app launch across iOS, Android, React Native, and Flutter.
Local code mapping. Translating a top stack frame or APM group name from production into a
Read+Grepagainst the user's repo so the fix lands in real code.Evidence-cited hypotheses. Every claim the agent makes cites the MCP tool result that produced it. No fabrication, no guessing.
Pattern library. Known mobile failure modes (Swift Concurrency races, Android ANRs, OOMs, network failures, APM latency regressions, failure-rate spikes) the agent recognizes and reaches for the right Luciq context to confirm.
Install
The fastest path is the plugin install. Add the marketplace and install:
Works in Claude Code and Cursor. The plugin install also wires up the Luciq MCP server in one step (this skill needs it).
After install, the skill is available as /luciq-skills:luciq-debug.
For other agents, install via npm:
Or copy SKILL.md from the public repo to ~/.claude/skills/luciq-debug/SKILL.md (user-global) or .claude/skills/luciq-debug/SKILL.md (project-local). The full SKILL.md is reproduced in the expandable below.
Prerequisites
The Luciq MCP server is configured and authenticated. The
luciq-setupskill wires this for first-time projects.The user has access to the Luciq application and environment they want to investigate.
The agent is running inside a project repository so it can map stack frames and APM groups to local source.
How the agent investigates
The skill runs the agent through a small, predictable loop. Every step is gated on evidence. If a step doesn't return data, the agent says so rather than filling in plausible-looking guesses.
Step 1. Identify the entry point
What kind of signal are we debugging?
Crash group
Crash number, fingerprint, or pasted stack trace
crash_details (or list_crashes to find it)
Specific occurrence of a crash
Crash number + ULID
get_occurrence_details
App hang / ANR
Hang number, or "recent UI hangs"
list_app_hangs
User-reported bug
Bug number
bug_details
Regression between versions
Two version numbers
list_crashes filtered by version, then crash_patterns with pattern_key: app_versions
Review / rating signal
Date range + version
list_reviews filtered by rating + app_version
APM performance regression
"what got slower/flakier since X", two versions; which metric
apm_list_groups for the matching metric sorted by apdex_change, then apm_group_view with dimensions
Worst APM group
The signal: slow endpoint/launch/screen, jank, flow drop-off
apm_list_groups for that metric sorted by its pain key (p95, failure_rate, frozen_frames_percent, dissat_count), then apm_group_view
Throughput spike / drop
Group + window
apm_group_view with throughput_chart for the group
If the user doesn't specify the signal type, the agent asks. It doesn't pick one at random.
Step 2. Pull MCP context
Once the entry point is known, the agent calls Luciq MCP tools in a deliberate order:
Crashes:
list_crashes,crash_details,crash_patterns, thenlist_occurrences_tokensandget_occurrence_detailsfor one or more sessions.Hangs:
list_app_hangsfiltered to the recent window.Bug reports:
list_bugsthenbug_details. The response includes URLs to compressed logs (network, console, session profiler) when available.Regressions: filter
list_crashesby the two versions, diff the result, then callcrash_patternswithpattern_key: app_versionsfor the highest-impact new groups.Review signals:
list_reviewsfiltered to low ratings, then correlate with crash and hang activity in the same window.APM regression: choose the
metricfor the signal, thenapm_list_groupssorted byapdex_change(signed delta) across the twoapp_versionvalues, take the most-degraded groups, thenapm_group_viewwithdimensionsto localize each regression to a cohort (OS, device, country, version), thenapm_occurrencewithselector: worstfor a concrete worst case to reason over.APM group deep dive:
apm_list_groupsfor the metric sorted by its pain key to find the group, thenapm_group_view—summaryfor the headline metrics, then the view that matches the pain:spans_table(orstages_breakdownfor launch/screen loading) for a slow segment,outliersfor the tail driving p95 (not onframe_drop), or thefailure_rateview for a failing network group, thenapm_occurrencefor the worst-failed request when the pain is failures, not the slowest.Reference material: before interpreting a metric's numbers, the agent reads that metric's reference files. Coverage gating, stage boundaries, and the conditions that make a number misleading aren't visible in the raw figure.
If an APM tool returns a 403 or 501, the agent skips that step and reports the reason. It does not infer "no regression" from a tool error.
The agent does not invent metrics that the Luciq MCP doesn't expose.
Step 3. Symbolicate if the trace is obfuscated (crash / hang track)
If the top frame is a hex address, an obfuscated symbol, or a <unknown> marker, the build is missing its symbol artifact:
iOS: dSYM upload.
Android: R8 / ProGuard mapping.
Flutter: split-debug-info.
React Native: source map.
The agent points the user at Luciq's symbol upload flow rather than reasoning over hex addresses.
Step 4. Map to local source
Crash / hang track — map the top frame:
Grepthe symbol (class + method) across the project.Readthe matched file with a small window around the offending line (10 lines above and below).For multi-platform projects (KMP, RN, Flutter), prefer the platform-specific source set first (
iosMain/,androidMain/).
APM track — map the endpoint or span to the call site:
The APM group name is the request signature (method + URL path template, e.g. GET /v2/orders/{id}). The agent maps it to the code that issues or handles it:
Grepthe path template, the host, or the path segments across the project. For a client SDK, that's the request-building call site. For a server repo, it's the route/handler registration.When
spans_tablelocalized the cost to one segment (a DB span, a downstream call, a serialization span), grep that segment's operation name — the bottleneck is usually inside that call, not in the request setup.Use the
dimensionsbreakdown to constrain the hypothesis: a regression confined to one OS version or device tier points at a different cause than one uniform across cohorts.
If the symbol or endpoint doesn't exist locally, the agent surfaces that fact rather than guessing at a fix.
Step 5. Form a hypothesis
Crash / hang track:
APM track:
Confidence is honest, not optimistic. Three corroborating MCP sources is high. Reasoning from the top frame or a single number alone is low. A latency figure with no cohort breakdown and no span decomposition is a symptom, not a root cause.
Step 6. Propose a fix
The agent shows a diff, explains how the fix addresses the root cause, and flags side effects. It does not apply the diff without user confirmation.
Pattern library
The skill carries a library of mobile failure patterns. Each pattern is a reference the agent reaches for when it sees the corresponding signature in the MCP data.
Swift Concurrency issues (iOS)
When the top frame involves async, await, an actor, or a Sendable violation:
Check whether the crash is a
Swift runtime: Fatal error: ...rather than a typical exception. That's a concurrency-safety check firing.Confirm the OS distribution from
crash_patternswithpattern_key: oses. Swift 6 strict-concurrency checks behave differently across iOS versions.Look at the session profiler from
get_occurrence_detailsfor hop-to-@MainActorpatterns near the crash time.Don't recommend slapping
@MainActoron a class to silence the error. Treat that as a smell, not a fix.
Android ANRs (ANDROID_FATAL_HANG)
When list_app_hangs returns an Android hang:
The
crash_causefield tells you where the main thread was blocked, but not always what blocked it. Pull a fewget_occurrence_detailsto see recent main-thread activity and pending I/O.Check
pattern_key: app_versionsto see whether the ANR is a regression or a long-tail issue.Common offenders: synchronous network calls on the main thread, large
SharedPreferences.commit()writes, blockingLockacquisitions, work scheduled on the wrong dispatcher.
iOS UI hangs (FATAL_UI_HANG)
The hang
exceptionsummary indicates duration class.Pull the occurrence to confirm what the user was doing. The
current_viewandapp_status(foreground / background) fields disambiguate.Common offenders: synchronous Core Data on
NSManagedObjectContext.viewContext, file I/O on the main queue, expensive layout work inviewDidLayoutSubviews.
Out-of-memory crashes
OOMs surface as terminations, not classic crashes. Check
crash_typeand the exception name.Pull the occurrence's
state.memoryandstate.storagefields fromget_occurrence_detailsfor the resource state at termination.Look at
pattern_key: devices. OOMs concentrate on lower-RAM devices and surface a device-tier story the agent should call out.
Network failure correlated crashes
For crashes with a stack frame in networking code, pull the occurrence's logs URL from
get_occurrence_details(compressed log archive).Cross-reference with bug reports in the same window via
bug_details. Thestate.logs.network_logURL often shows the failed request that preceded the crash.Don't assume timeout vs DNS failure vs server error without the log evidence. The categories matter for the fix.
APM latency regression
When apm_list_groups sorted by apdex_change shows a group degrading between versions:
Before trusting the apdex, the agent sanity-checks
threshold_msagainst50th_percentile_ms, then weighs it against the endpoint's business role: a list/read call should be near-real-time, a few hundred ms; a heavy export doesn't need to be. A target set for the wrong role is a config fix, not a code fix.Confirm with absolute numbers: pull
apm_group_view summaryfor50th_percentile_msand95th_percentile_msbefore and after.Always run
dimensionsto localize. A regression confined to one OS version or device tier is a different bug than one uniform across cohorts.Use
spans_tableto attribute the time. The fix targets the dominant span. Chasing the request-setup code when the cost is in a DB span wastes effort.Use
outlierswhen p95/p99 moved but the median didn't — the tail requests carry the signature.
APM app launch
When apm_list_groups flags a launch group (metric: launch):
Segment by
typefirst. Cold, warm, and hot launches measure different windows, so aggregating across them — or across platforms — produces a meaningless number.Attribute with
stages_breakdown, notspans_table. The dominant stage maps to code via the platform's optimization-targets table; on React Native and Flutter, a dominant native stage means the cause isn't in JS or Dart.Use
dimensionswithpattern_key: first_screento find which entry screen carries the cost, andoutlierswhen p95 moved but p50 didn't.The agent validates the number before quoting it — several conditions can make a launch total mean something other than "the app is slow," and they aren't visible in the number itself.
APM network
When apm_list_groups flags a network group (metric: network):
Coverage comes first. Capture isn't automatic on Android or Flutter, so the agent checks the codebase before reading absence as a measurement.
There's no
stages_breakdownview for network. The agent attributes withspans_tableand usesapm_occurrencefor one request's stage detail.The list row gives
latency_p95_msandfailure_rateonly — no p50, no occurrence count. Those come fromsummaryordimensions.The agent segments on
radiobefore comparing latency, and accounts for what the measured window excludes — the app's own queueing and interceptors aren't in it.
APM failure-rate spike
When apm_list_groups sorted by failure_rate flags a group:
Split
total_failure_rateintoclient_failure_ratevsserver_failure_rate. Client failures (4xx, timeouts, cancellations) point at the app; server failures (5xx) point at the backend. They lead to opposite fixes.Both native platforms distort the client-side rate, in opposite directions, so the agent applies the platform-specific correction before quoting it.
Filter the group by
failure_name/failure_typeto see whether it's one error class or many.Cross-reference the window with
list_crashesandbug_details— a failure-rate spike that coincides with a crash spike on the same call path is usually one root cause, not two.
APM throughput change
When throughput_chart shows a spike or drop:
A drop in throughput with flat latency often means callers stopped calling — a client-side gating change, a feature flag, a rollout — not a performance defect. Check
dimensionsbyapp_versionand correlate with a release.A spike with rising latency is load-driven; the fix is usually capacity or backpressure, not a code path. Say which the evidence supports.
Honest about what's out of scope
The skill is grounded in what Luciq MCP exposes today. It deliberately does not:
Compute crash-free session rate or any metric the MCP doesn't return.
Reason about App Store rating drops as a primary investigation entry point.
list_reviewsis correlation, not causation.Pretend to have data it doesn't have. If a query returns nothing, the agent surfaces that fact and stops.
When Luciq MCP grows new tools (release comparison, session replay context), this skill grows with them.
When to reach for it
A new crash spikes in production and you want a triage and a candidate fix without leaving your IDE.
A user-reported bug has reproduction steps but you don't know which screen they were on or what network call failed. The agent pulls that from
bug_detailsand points you at the file.You're cutting a release and want a quick diff of new crashes between versions. The agent runs the comparison via
list_crashesandcrash_patterns.You're handed a crash by a teammate with just a number. The agent investigates from the number alone.
You saw an apdex drop or a p95 spike on an endpoint since the last release. The agent finds the worst-affected group, decomposes the time via
spans_table, and maps the bottleneck to local source.
Last updated