What the agent does
The agent clones the repository into its own cloud sandbox and starts from the trace you describe: book and chapter pages at 3 s p95 instead of 400 ms, the time spent in database queries, after a permissions change in the last release. Time in queries after a permissions change narrows the search to two places: the SQL that decides what the current user may see, and how many times a page runs it.
In an app like BookStackApp/BookStack it follows a book page from the route to the database. BookController::show loads the book, then builds the contents with (new BookContents($book))->getTree(true) at line 132. app/Entities/Tools/BookContents.php loads the book's visible pages through PageQueries::visibleForList, which adds a correlated book_slug subquery per row, and its visible chapters with scopes('visible'). Every one of those goes through scopeVisible in app/Entities/Models/Entity.php, which calls PermissionApplicator::restrictEntityQuery. A chapter page does the same work and more: ChapterController::show loads the chapter's pages at line 87 and then the whole book tree again at line 89 for the navigation.
restrictEntityQuery at line 99 of app/Permissions/PermissionApplicator.php is the heart of it. For every candidate row it adds a whereHas('jointPermissions') subquery that filters joint_permissions by the user's role ids, groups by entity_type and entity_id, and keeps the row only if max(status) and max(owner_id) pass a HAVING clause. The agent reads the indexes that subquery can use: the 2023 storage refactor indexed status and owner_id separately, alongside the older role_id and (entity_id, entity_type) indexes. It notes that the query's cost grows with the number of roles a user has and the number of joint_permissions rows per entity, both of which a permissions change can multiply, and that bookstack:regenerate-permissions rebuilds the table.
Last, it reads the 30 most recent commits with git log -p, looking for changes to PermissionApplicator, JointPermissionBuilder, EntityPermissionEvaluator, the entity queries and the migrations, and for any new call that runs a permission check per item in a loop. If it needs to see the SQL, it runs the PHPUnit tests that cover these pages in the sandbox with MySQL and the query log on. It writes incident.md and changes no code.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Incident: Datadog APM shows the book and chapter pages at 3 s p95, up from 400 ms, with the time in database queries, after a permissions change in the last release. Read the code, the configuration and the last 30 commits, find the most likely causes, and write incident.md with a timeline, each suspect with file and line evidence, and the check that would confirm or clear it. Change no code.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- 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.
- 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.
- 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, attached to the session as an artifact. It opens with the commits in the last release that touched permissions, queries or migrations, then ranks the suspects. Each names the file and line, describes the query it produces and why that query got slower, and gives the check: the slowest query spans on the book page's trace in Datadog APM, EXPLAIN on the permission subquery with a real user's role ids, the row count of joint_permissions per entity before and after the release, or the number of permission queries a single chapter page issues.
Where the agent ran tests or captured SQL in the sandbox, the report quotes the statements and the counts and marks them as sandbox results on test data. The session's transcript keeps every command and every file read.
A reviewer checks the top suspect against the production trace first. If the cause is a stale or oversized joint_permissions table, the fix may be operational (regenerating permissions) rather than code; if it is a query or a missing index, a follow-up to the same session can ask the agent to write the change as a pull request with a test.
Run it on every Datadog latency monitor
A Datadog monitor on p95 latency for a resource can notify a webhook. Point it at a handler on your server that sends this request with the resource names, the before and after numbers and the release in the prompt, so each regression starts its own investigation.
With a webhook URL on the API key, Rush POSTs run.completed when the turn finishes; your handler adds the report's link to the monitor's event or the incident.
The use case this job follows, with its automation and trigger: Investigate an incident.
Why run it on Rush?
Permission-aware queries are hard to read in a trace and harder to read in code, because one scope adds a grouped subquery to every list on the page. The agent traces that path from controller to SQL across the whole repository in its own sandbox, with PHP, Composer and MySQL available to run the tests and log the queries, without loading anything into a shared database.
Every suspect comes with its file and line and every measurement with its command, kept in the session's transcript. If several pages regressed at once, each can be investigated in its own run, up to the key's concurrent run limit.
Frequently asked questions
Can the agent read our Datadog traces directly?
Yes, if you connect Datadog's MCP server and name the connection in the request. It can then search the slow traces and spans itself instead of relying on the numbers in the prompt. Without it, the report tells you which spans to open.
Why would a permissions change slow down pages that did not change?
In apps like BookStack, every list of books, chapters and pages filters rows through a permissions table. A change that adds roles, per-item overrides or rows to that table makes every one of those filters more expensive, even on pages nobody edited.
Will it add indexes or run migrations?
No. The prompt says to change no code, and the agent works on its own copy in the sandbox. The report may recommend an index, with the EXPLAIN evidence for it, for your team to decide on.
Does it work with Telescope, Debugbar or Clockwork output?
Yes. BookStack ships Clockwork as a dev dependency, and the agent can use it or Laravel's query log in the sandbox. You can also attach an export from Telescope or Debugbar captured in production to the request.