All jobs

Fix a Laravel App Bug From a Datadog Monitor Alert

Yes. A Datadog monitor starts a run; the agent reads its logs and traces, fixes the Laravel code with a PHPUnit test, runs php artisan test and opens a pull request.

Run this on RushIn a Project that has your repository.

What the agent does

When the monitor fires, the agent reads it through the Datadog connection, then the error logs and APM traces for the service from the 30 minutes around the alert. A Laravel app traced with Datadog's PHP tracer reports each request under its route and controller action, and an exception's class, message and stack trace come with the error span. In a Laravel app like BookStackApp/BookStack, that is enough to tell a failing page save in PageController from a permission check that throws on a book listing.

It reads the code in its sandbox, following the stack trace from the controller into the services. Page writes go through app/Entities/Repos/PageRepo.php: publishDraft, update, updatePageDraft, restoreRevision and move. Visibility goes through app/Permissions/PermissionApplicator.php, whose checkOwnableUserAccess decides a single item and whose restrictEntityQuery and restrictPageRelationQuery add the joins that hide what a user may not see, with JointPermissionBuilder.php keeping the joint permission table those queries read. A 500 that only some users hit often comes from this layer, so the agent compares the user roles in the failing traces with the ones that succeed.

It writes a PHPUnit test in the area the trace points at, using the helpers BookStack's tests already use: $this->entities->page() for a fixture and $this->asEditor() or a user with a custom role for the request. Page bugs go in tests/Entity/PageTest.php; permission bugs in tests/Permissions/EntityPermissionsTest.php or RolePermissionsTest.php. The suite's phpunit.xml sets DB_CONNECTION to mysql_testing, so the agent starts MySQL in the sandbox and migrates the test database before it runs php artisan test, first the one file, then everything.

Then it opens a pull request that quotes the exception and the log lines, names the route and the role from the trace, links the monitor and explains the cause. A fix in the permission layer carries a test for both sides: the user who should now see the item and the one who still must not.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "A Datadog monitor on this Laravel service fired; its webhook payload follows this prompt. Use the Datadog connection to read the monitor and the error logs and APM traces from the 30 minutes around the alert, including the exception class, stack trace, route and the user's role. Find the code path that produced them, starting from the page repository in app/Entities/Repos/PageRepo.php and the permission services in app/Permissions/. Write a PHPUnit regression test with the existing test helpers, start MySQL for the mysql_testing connection, fix the code, run php artisan test, and open a pull request that quotes the log lines the fix addresses and links the monitor. A permission fix must test both a user who may and one who may not see the item.\n\nMonitor payload:\n{payload}",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ],
  "connections": [
    "datadog"
  ]
}
  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

A pull request lands on your repository with the fix, typically in a repository class under app/Entities/Repos/ or a method of PermissionApplicator, and new test methods in the matching file under tests/. The description has the quoted exception and log lines, the route and role from the trace, the monitor link and the php artisan test summary. Your CI runs on it as on any other pull request.

The session's result, which arrives as data.result on the run.completed webhook, is the agent's account of the cause and the change. Its transcript keeps every Datadog query and answer, the MySQL setup and each test run's output, so a reviewer can see exactly what was tested and against which database.

In review, a permission change deserves the slowest read: check that the new test denies access where it should, that no query lost its restrictEntityQuery call, and that the fix does not grant a role more than the original bug report needed. For a page save fix, check that revisions and drafts still behave as PageRevisionTest and PageDraftTest expect.

Run it on every Datadog monitor alert

In the Project for this app, add an automation with a webhook trigger, this prompt and a saved agent that names the Datadog connection. In Datadog's Webhooks integration, create a webhook to the trigger's URL with the trigger's secret as a bearer token and reference it as @webhook-<name> in the monitor message. Each alert body then follows the prompt as event text, and max_runs_per_hour keeps a flapping monitor from starting a run every minute.

From your own server, the same run is POST /o/{org}/sessions with this request, the alert payload appended to input and the alert id as the Idempotency-Key. Set a webhook on the API key to be told when the run finishes, with the summary in data.result.

The use case this job follows, with its automation and trigger: Fix a bug from an alert.

Why run it on Rush?

Reproducing a Laravel bug that depends on a user's role needs a database, seeded fixtures and the test suite, which is a lot to set up at the moment an alert fires. A Rush run brings up MySQL and PHP in its own sandbox, reads Datadog with your connection, and runs php artisan test for real, with the output kept on the session.

Each alert runs on its own, so two monitors firing on the same night are fixed in parallel on separate branches. The pull request carries its proof, the production logs and a test that fails without the fix, which is what lets a reviewer merge a permission change with confidence.

Frequently asked questions

Does the sandbox have MySQL?

The sandbox is a full Linux computer, so the agent can install and start MySQL or MariaDB and create the test database the suite expects. Name your own database setup in the prompt if it differs from phpunit.xml.

Will it change roles or permissions in my production data?

No. It works on a clone and a throwaway test database, and reads Datadog only. The fix reaches production only when someone merges and deploys it.

What if the exception comes from a package, not my code?

The agent says so and points to the package and version from composer.lock. It can open a pull request that works around it or pins a fixed version, but it explains the trade-off first.

Which Datadog site is supported?

The catalog's Datadog connection covers the US1 site. For another site, connect that site's MCP server as a custom connection and name it in connections.