# luciq-debug

Investigate a Luciq production signal end to end (crash, hang, or user-reported bug) using the [Luciq MCP server](/product-guides-and-integrations/product-guides/ai-features/luciq-mcp-server.md) for context and the user's local repository for the code mapping. Form a hypothesis, propose a fix, cite the evidence.

This is the customer-asked-for skill: when an engineer types *"why is this crashing on iOS 18?"* or *"investigate bug #4821"* in their IDE, they don't want a list of API calls. They want the agent to debug like an experienced mobile engineer would, with Luciq's data as backing.

## 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"*.

## What the agent learns

`luciq-debug` turns the agent into an evidence-based debugger:

* **Signal-typed methodology.** Different decision trees for crashes, hangs, and bug reports, 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.
* **Local code mapping.** Translating a top stack frame from production into a `Read` + `Grep` against the user's repo so the fix lands in real code, not pseudo-code.
* **Evidence-cited hypotheses.** Every claim the agent makes about the cause 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) 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:

```
/plugin marketplace add github.com/luciqai/agent-skills
/plugin install luciq-skills@luciq.ai
```

Works in **Claude Code** and **Cursor**. The plugin install also wires up the [Luciq MCP server](https://github.com/luciqai/luciq-docs/blob/main/home/product-guides-and-integrations/product-guides/luciq-mcp-server/README.md) in one step (this skill needs it).

After install, the skill is available as `/luciq-skills:luciq-debug`.

For other agents, install via npm:

```bash
npx luciq-skills install            # project-local
npx luciq-skills install --global   # all projects
```

Or copy [`SKILL.md`](https://github.com/luciqai/agent-skills/blob/main/plugins/luciq-skills/skills/luciq-debug/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.

<details>

<summary>📋 Click to expand the full SKILL.md</summary>

````markdown
---
name: luciq-debug
description: Use when the user wants to investigate a Luciq production signal end to end, propose a code fix, or answer "why is this happening". Triggers include pasting a crash ID, fingerprint, or stack trace; mentioning a Luciq bug number, hang, or ANR; asking "what broke since version X"; flagging a rating drop or review spike; or asking why a session crashed, hung, or terminated. Pulls evidence via the Luciq MCP server, maps it to local source, forms an evidence-cited hypothesis.
---

# Luciq Production Debugging

Investigate a Luciq production signal end to end. Default to evidence-based reasoning. Cite the MCP tool result that supports each claim. If a query returns nothing, surface that fact instead of filling in plausible-looking guesses.

## When NOT to use this skill

- First-time SDK install or wiring `Luciq.start(...)`, use `luciq-setup`.
- Renaming Instabug symbols to Luciq, or upgrading between Luciq SDK versions, use `luciq-migrate`.
- General mobile debugging where Luciq is not the data source. This skill is grounded in what the Luciq MCP exposes; without that, do not pretend to use it.

If the user's request fits any of the above, STOP and route them to the right skill rather than running this one.

## Prerequisites

The Luciq MCP server must be configured and authenticated. If MCP tools are not available, STOP and direct the user to https://docs.luciq.ai/product-guides-and-integrations/product-guides/ai-features/luciq-mcp-server/setup-by-ide for setup, or run `luciq-setup` to wire it.

The MCP exposes (verbatim names):

| Tool | Purpose |
| --- | --- |
| `list_applications` | List apps and their tokens for the authenticated user. |
| `list_crashes` | List crash groups with filters (version, OS, date range). |
| `crash_details` | Full details for a crash group: top frames, occurrence sample, distributions. |
| `crash_patterns` | Distribution by `pattern_key` (e.g. `oses`, `app_versions`, `devices`). |
| `list_occurrences_tokens` | Occurrence ULIDs for a crash group, paginated. |
| `get_occurrence_details` | Per-occurrence detail: session profiler, logs URLs, device state. |
| `list_app_hangs` | Hang and ANR groups. iOS surface as `FATAL_UI_HANG`, Android as `ANDROID_FATAL_HANG`. |
| `list_bugs` | User-reported bugs. |
| `bug_details` | Full bug detail including compressed log archive URLs. |
| `list_reviews` | App Store / Play Store reviews filtered by `rating` and `app_version`. |

YOU MUST cite which of these produced any piece of evidence in your hypothesis. Do not invent capabilities the MCP does not expose. See "Out of scope" below for what the MCP deliberately does not return.

## Workflow

Run the following loop. Every step is gated on evidence.

### Step 1. Identify the entry point

Determine the kind of signal being debugged. If the user has not specified, ask. Do not pick at random.

| Entry point | Required input | First MCP tool to call |
| --- | --- | --- |
| Crash group | Crash number, fingerprint, or pasted stack trace | `crash_details` (or `list_crashes` to find it first) |
| Specific occurrence of a crash | Crash number plus ULID | `get_occurrence_details` |
| App hang or 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 or rating signal | Date range and version | `list_reviews` filtered by `rating` and `app_version` |

### Step 2. Pull MCP context

Sequence the available Luciq MCP tools deliberately for the entry point:

- Crashes: `list_crashes`, `crash_details`, `crash_patterns`, then `list_occurrences_tokens` and `get_occurrence_details` for one or more sessions.
- Hangs: `list_app_hangs` filtered to the recent window. iOS hangs surface as `FATAL_UI_HANG`, Android as `ANDROID_FATAL_HANG`.
- Bug reports: `list_bugs` then `bug_details`. The response includes URLs to compressed logs (network, console, session profiler) when available.
- Regressions: filter `list_crashes` by the two versions, diff the result, then call `crash_patterns` with `pattern_key: app_versions` for the highest-impact new groups.
- Review signals: `list_reviews` filtered to low ratings, then correlate with crash and hang activity in the same window.

### Step 3. Symbolicate if obfuscated

If the top frame is a hex address, an obfuscated symbol, or `<unknown>`, the build is missing its symbol artifact (dSYM for iOS, R8/ProGuard mapping for Android, split-debug-info for Flutter, source map for React Native). STOP and direct the user to upload symbols before continuing. Do not reason over hex addresses.

### Step 4. Map the top frame to local source

For the symbolicated top frame:

- `Grep` the symbol (class plus method) across the project.
- `Read` the 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/`).

If the symbol does not exist locally, the project is at a different commit than the build the crash came from. Surface that fact rather than guessing at a fix.

### Step 5. Form a hypothesis

Use this structure exactly. Cite each piece of evidence to the MCP tool that produced it.

```
HYPOTHESIS: <one sentence>
CONFIDENCE: <low / medium / high>

EVIDENCE:
- Top frame: <file>:<line> - <symbol>     [from: crash_details]
- Distribution: <e.g. only iOS 18.0+>     [from: crash_patterns]
- Repro context: <e.g. backgrounded for ~5s>  [from: get_occurrence_details]
- Correlated signal: <e.g. matching review text>  [from: list_reviews]

ROOT CAUSE: <the specific defect>
```

Confidence is honest. Three corroborating MCP sources is high. Reasoning from the top frame alone is low.

### Step 6. Propose a fix

Show a diff. Explain how the fix addresses the root cause. Flag any side effects. Optionally write a failing test that reproduces the issue before applying. Do not apply the diff without user confirmation.

## Pattern library

Carry these patterns. Reach for them when the corresponding signature appears in the MCP data.

### Swift Concurrency (iOS)

When the top frame involves `async`, `await`, an actor, or a `Sendable` violation:

- Check whether the crash is `Swift runtime: Fatal error: ...` rather than a typical exception. That is a concurrency-safety check firing.
- Confirm OS distribution via `crash_patterns` with `pattern_key: oses`. Swift 6 strict-concurrency checks behave differently across iOS versions.
- Look at the session profiler from `get_occurrence_details` for hop-to-`@MainActor` patterns near the crash time.
- Do not recommend slapping `@MainActor` on 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_cause` field tells you where the main thread was blocked, but not always what blocked it. Pull a few `get_occurrence_details` to see recent main-thread activity and pending I/O.
- Check `pattern_key: app_versions` to 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, blocking `Lock` acquisitions, work scheduled on the wrong dispatcher.

### iOS UI hangs (`FATAL_UI_HANG`)

- The hang `exception` summary indicates duration class.
- Pull the occurrence to confirm what the user was doing. The `current_view` and `app_status` (foreground / background) fields disambiguate.
- Common offenders: synchronous Core Data on `NSManagedObjectContext.viewContext`, file I/O on the main queue, expensive layout work in `viewDidLayoutSubviews`.

### Out-of-memory crashes

- OOMs surface as terminations. Check `crash_type` and the exception name.
- Pull the occurrence's `state.memory` and `state.storage` fields from `get_occurrence_details` for 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`. The `state.logs.network_log` URL often shows the failed request that preceded the crash.
- Do not assume timeout vs DNS failure vs server error without log evidence. The categories matter for the fix.

## Out of scope

The skill is grounded in what the Luciq MCP exposes today. It deliberately does not:

- Compute crash-free session rate or any aggregate metric the MCP does not return.
- Reason about App Store rating drops as a primary investigation entry point. `list_reviews` is correlation, not causation.
- Propose APM regression analysis from MCP data. The MCP does not expose APM span aggregates yet.

When new MCP tools land (release comparison, APM aggregates, session replay), this skill grows with them. Until then, if the user asks for one of those, say so plainly.

## Style

- Do not fabricate stack traces, line numbers, or counts.
- Do not propose a fix without naming the root cause.
- Do not apply edits without showing a diff and getting confirmation.
- If MCP returns nothing for a query, surface that. Do not fill in plausible-looking data.

## Red Flags - STOP and surface to the user

If you catch yourself thinking any of these, you are about to ship a fabricated investigation. STOP, surface to the user, do not proceed:

- "MCP returned nothing, but the user clearly wants an answer, so I'll reason from the symbol name." That is a guess, not a hypothesis. Surface the empty result.
- "The top frame is a hex address but I can probably figure it out from context." Do not. Stop and ask the user to upload symbols.
- "The local symbol doesn't exist but the file looks similar enough." It isn't. The repo is at a different commit; surface that.
- "I'll quote a crash-free session rate from memory." The MCP does not expose that metric. Saying you computed it from MCP data is a fabrication.
- "Confidence is high because the top frame matches my prior." One source is not three. Lower confidence to low or medium.
- "I'll apply the fix without a diff because it's obviously right." Show the diff. Get confirmation. Always.
- "The hypothesis cites the symbol but not which MCP tool produced it." Add the citation, or weaken the hypothesis.

The pattern: every shortcut here trades "sounds confident" for "actually true." The skill's job is to be true.
````

</details>

## Prerequisites

* The [Luciq MCP server](/product-guides-and-integrations/product-guides/ai-features/luciq-mcp-server.md) is configured and authenticated. The [`luciq-setup`](/product-guides-and-integrations/product-guides/ai-features/agent-skills/luciq-setup.md) skill 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 to local source.

{% hint style="info" %}
If the MCP server isn't connected, the skill stops and points the user to [Setup by IDE](/product-guides-and-integrations/product-guides/ai-features/luciq-mcp-server/setup-by-ide.md) before continuing.
{% endhint %}

## 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?

| Entry point                    | Required input                                   | First MCP tool call                                                                        |
| ------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| 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`                                        |

If the user doesn't specify, 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. The full tool reference lives in [MCP Tools Reference](/product-guides-and-integrations/product-guides/ai-features/luciq-mcp-server/mcp-tools-reference.md); this skill teaches sequencing on top of that reference.

For each entry point, the skill weights data sources differently:

| Signal            | Primary                                                       | Secondary                                                            | Tertiary                                                                |
| ----------------- | ------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| Crash             | `crash_details` (stack, exception, versions)                  | `crash_patterns` by `devices` / `oses` / `app_versions`              | `list_occurrences_tokens` then `get_occurrence_details` for one session |
| App hang          | `list_app_hangs` filtered to the recent window                | Hang patterns by view / OS                                           | One occurrence's session profiler if exposed                            |
| User-reported bug | `bug_details` (steps, screenshots, network logs, device)      | The session's logs from the URLs in the response                     | n/a                                                                     |
| Regression        | `list_crashes` filtered by both versions, diffed              | `crash_patterns` by `app_versions` for the new top issues            | Per-occurrence detail for the highest-impact regression                 |
| Review signal     | `list_reviews` filtered by `rating: [1, 2]` and `app_version` | `list_crashes` / `list_app_hangs` in the same window for correlation | n/a                                                                     |

**The agent does not invent metrics that Luciq MCP doesn't expose.** Cross-version aggregates beyond what `crash_patterns` returns, custom percentiles on hang duration, or computed crash-free session rates are out of scope until the MCP server exposes them.

### Step 3. Symbolicate if the trace is obfuscated

If the top frame is a hex address, an obfuscated symbol, or a `<unknown>` marker:

* iOS: dSYM upload check.
* Android: R8 / ProGuard mapping check.
* Flutter: split-debug-info check.
* React Native: source map check.

The agent points the user at Luciq's symbol upload flow rather than reasoning over hex. (A dedicated `luciq-symbolicate` skill is in development; until it ships, the agent links to the public symbol upload docs and stops.)

### Step 4. Map the top frame to local source

For the symbolicated top frame:

* `Grep` the symbol (class + method) across the project.
* `Read` the matched file with a small window around the offending line.
* For multi-platform projects (KMP, RN, Flutter), prefer the platform-specific source set first (`iosMain/`, `androidMain/`).

If the symbol doesn't exist locally, that's evidence the project is at a different commit than the build the crash came from. The agent surfaces that rather than guessing.

### Step 5. Form a hypothesis

The agent assembles the evidence into a structured hypothesis. Format:

```
HYPOTHESIS: <one sentence>
CONFIDENCE: <low / medium / high>

EVIDENCE:
- Top frame: <file>:<line> - <symbol>     [from: crash_details]
- Distribution: <e.g. only iOS 18.0+>     [from: crash_patterns]
- Repro context: <e.g. backgrounded for ~5s>  [from: get_occurrence_details]
- Correlated signal: <e.g. matching review text>  [from: list_reviews]

ROOT CAUSE: <the specific defect>
```

Confidence is honest, not optimistic. If three sources agree, that's high. If the agent is reasoning from the top frame alone, that's low.

### Step 6. Propose a fix

The agent shows a diff. Explains how the fix addresses the root cause. Flags side effects. Optionally writes a failing test that reproduces the issue before applying the fix.

The agent does not apply the diff without confirmation.

## Pattern library

The skill carries a small, focused library of mobile failure patterns. Each pattern is a short 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_patterns` with `pattern_key: oses`. Swift 6 strict-concurrency checks behave differently across iOS versions.
* Look at the session profiler from `get_occurrence_details` for hop-to-`@MainActor` patterns near the crash time.
* Don't recommend slapping `@MainActor` on 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_cause` field tells you where the main thread was blocked, but not always what blocked it. Pull a few `get_occurrence_details` to see the recent main-thread activity and any pending I/O.
* Check `pattern_key: app_versions` to see whether the ANR is a regression or a long-tail issue.
* Common offenders the agent should look for in local code: synchronous network calls on the main thread, large `SharedPreferences.commit()` writes, blocking `Lock` acquisitions, work being scheduled on the wrong dispatcher.

### iOS UI hangs (`FATAL_UI_HANG`)

* The hang `exception` summary indicates duration class.
* Pull the occurrence to confirm what the user was doing. The `current_view` and `app_status` (foreground / background) fields disambiguate.
* Common offenders: synchronous Core Data on `NSManagedObjectContext.viewContext`, file I/O on the main queue, expensive layout work in `viewDidLayoutSubviews`.

### Out-of-memory crashes

* OOMs surface as terminations, not classic crashes. Check `crash_type` and the exception name.
* Pull the occurrence's `state.memory` and `state.storage` fields from `get_occurrence_details` for 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`. The `state.logs.network_log` URL 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.

## 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_reviews` is correlation, not causation.
* Propose APM regression analysis from MCP data. The MCP doesn't expose APM span aggregates yet.
* 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, APM aggregates, session replay context), this skill grows with them.

## Customize for your team

The skill ships with the patterns above, but every team has its own recurring failure modes. You can extend it with team-specific knowledge by adding files in your project's skills directory:

* `kb/patterns.md`. Failure patterns the agent should recognize for your codebase.
* `kb/integrations.md`. Your custom networking, database, or analytics layers the agent should inspect when their stack frames appear.
* `kb/ownership.md`. Who owns which subsystem so the agent can route a triaged crash to the right person.

Tell the agent *"remember that for this codebase, X"* and it will append to the right knowledge base file. The skill picks the additions up on the next invocation.

## 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_details` and 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_crashes` and `crash_patterns` and tells you what's changed.
* You're handed a crash by a teammate with just a number. The agent investigates from the number alone.

This is the skill that makes the time-from-crash-report-to-fix short, *and* the resulting fix grounded in real production evidence.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.luciq.ai/product-guides-and-integrations/product-guides/ai-features/agent-skills/luciq-debug.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
