# Investigate a Laravel App Incident With Sentry

Yes. An agent reads the incident window in Sentry, compares it with your recent Laravel commits and writes a cited incident report without changing code.

[Run this on Rush](https://cloud.getrush.ai/run/investigate-sentry-spike/laravel/), in a Project that has your repository.

## What the agent does

The agent starts in its own cloud sandbox with your repository cloned and Sentry reachable through the Sentry connection, which queries issues, events and traces. It reads the errors for the window given in the prompt: each issue's title, exception class, first and last seen, event count, the release it was first seen in, and the stack frames that point into your code. It writes down every query it makes so the report can list them.

Then it reads the code those frames point to. In a Laravel app like koel, the music server, it reads `composer.json` and finds PHP `>=8.3`, `laravel/framework` `^13.0`, `sentry/sentry-laravel` `^4.27` and PHPUnit 11, with the test command `php artisan test --parallel`. The routes are in `routes/api.base.php`: `Route::apiResource('songs', SongController::class)` plus `PUT` and `DELETE` on `songs`, and `Route::apiResource('playlists.songs', PlaylistSongController::class)` with a separate `DELETE playlists/{playlist}/songs` and `POST playlists/{playlist}/songs/move`. It follows a failing frame from `app/Http/Controllers/API/PlaylistSongController.php`, whose `index` calls `SongRepository::getByPlaylist` and whose `store` calls `PlaylistService::addPlayablesToPlaylist`, down into `app/Repositories/SongRepository.php`, where `getByStandardPlaylist` left-joins `playlist_song` and `playlists` and, on a Plus license, joins `users as collaborators`.

Next it compares the incident with the history. It reads the commits from the last 7 days that touch the song and playlist controllers, their form requests under `app/Http/Requests/API`, the repositories and `app/Services/Playlist/PlaylistService.php`, and lines up each commit's time with when each Sentry issue was first seen. A new issue that first appears in the release containing a given commit, with frames in the lines that commit changed, ranks at the top; an issue that existed before the window ranks low, even if it is loud.

Where it can, the agent reproduces the failure locally. `phpunit.xml.dist` runs the tests on SQLite in memory, so it runs the existing feature tests for songs and playlists and, if the cause is clear, writes a failing test in the sandbox to show it, without committing it. It changes no code in the repository and opens no pull request; what it adds to the evidence is the test output.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Error rates for this Laravel app rose in the window given after this prompt. Use the Sentry connection to read the errors, logs or metrics for that window, compare them with the commits to the song and playlist controllers, their requests, repositories and PlaylistService in the last 7 days, and write incident.md with a timeline, the most likely cause, the evidence behind each claim and the Sentry queries you ran. Run the existing song and playlist feature tests with php artisan test and include their output. Change no code and open no pull request.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is `incident.md` as an artifact on the session, with a download link the session read returns. It opens with a timeline that interleaves the Sentry issues, by first-seen time and event count, with the commits from the last 7 days. Then it names the most likely cause: the commit, the file and line it changed, the Sentry issue whose frames point there, and why one produces the other. Other candidates follow, each with what speaks for and against it.

Each claim cites its evidence: a Sentry issue id and the query that found it, a commit hash, a quoted line, or the output of `php artisan test`. The report ends with the queries the agent ran, so the next person can rerun them. The session's transcript keeps every command and every Sentry call with its answer.

Before anyone acts on it, the on-call engineer checks the named commit against the release Sentry attributes the errors to, and decides whether to roll back or fix forward. A follow-up message to the same session can ask the agent to write the fix with a test and open a pull request, since the sandbox still holds the repository.

## Run it on every Sentry issue alert

Sentry alert rules can call a webhook when a new issue appears or an issue's frequency jumps. A handler on your server can turn that into this request, with the alert's time window after the prompt, so a report is written for every alert that fires.

Set a webhook URL on the API key and Rush POSTs `run.completed` when the turn finishes. The handler reads `incident.md` from the session's artifacts and posts it to the incident channel, so the first human look starts from a timeline and a ranked cause.

## Why run it on Rush?

Correlating a Sentry spike with recent commits is slow on a laptop in the middle of an incident: switching between the Sentry UI, `git log` and the code, installing PHP dependencies to run a test, and keeping notes of what was checked. In a Rush sandbox the agent runs `composer install` and the PHPUnit suite on its own disk and reads Sentry through your connection, while the engineer handles production.

The report is a record, not a guess: every claim has a Sentry query, a commit or a test run behind it, and the session keeps the full transcript. Separate incidents, or the same incident across several services, can each get their own run at once, up to the key's concurrent run limit.

## Frequently asked questions

### How does the agent get access to Sentry?

Connect Sentry once with `POST /me/connections` as an MCP server, which signs in with OAuth, then name the connection in the run's `connections` field or in a saved agent. The run sees only the connections it names.

### Will it change my code or open a pull request?

No. The prompt says to change no code, and the only output is the Markdown report. Any test it writes to reproduce the error stays in the sandbox and is quoted in the report.

### Does it need my production database?

No. koel's `phpunit.xml.dist` runs tests on SQLite in memory, so the agent can run the feature tests in the sandbox. If your tests need MySQL or Postgres, it starts one in the sandbox for the run.

### What if the cause is not in the last 7 days of commits?

The report says so. It lists the issues that predate the window as older problems and points at what else changed, such as a dependency in `composer.lock` or configuration, when the evidence leads there.
