What the agent does
A Rust service reports to Sentry either a panic, with the message and the frames of the thread that unwound, or an error event from its tracing layer. The agent reads the alert payload after the prompt, then uses the Sentry connection to fetch the issue and its latest event: the kind, the message, the frames with their crate and function names, and any tracing fields attached as tags. From those it decides which crate in the workspace to open.
In a Rust service like lldap/lldap the workspace in Cargo.toml has server, app, migration-tool, set-password and the crates under crates/: ldap, graphql-server, domain, domain-handlers, domain-model, sql-backend-handler, auth, access-control, opaque-handler and validation. rust-toolchain.toml and rust-version both pin 1.91.0, and the workspace uses edition 2024. The LDAP side is crates/ldap/src/handler.rs, whose LdapHandler exposes do_bind, do_search_or_dse, do_extended_request, do_modify_request, create_user_or_group, delete_user_or_group, do_compare and handle_ldap_message, with the operation bodies in search.rs, modify.rs, create.rs, delete.rs, compare.rs and password.rs. The GraphQL side is crates/graphql-server/src/mutation/mod.rs, with create_user, update_user, update_group, add_user_to_group, delete_user, add_user_attribute and the object-class mutations, and the queries under query/. Errors flow through DomainError in crates/domain-model/src/error.rs, and server/src/ldap_server.rs and graphql_server.rs wire both into actix.
The repository tests at the crate level, so the agent puts its test where the neighbours are. handler.rs holds the LDAP tests, built on LdapHandler::new_for_tests with a mockall backend and the setup_bound_admin_handler, setup_bound_readonly_handler and setup_bound_password_manager_handler helpers; the mutation module has its own #[tokio::test] cases such as test_create_user_attribute_valid. The agent adds a test that sends the request the Sentry event implies, a search filter, a modify on an attribute, or a mutation input, with the mock backend returning what the breadcrumbs show, and runs cargo test -p lldap_ldap <name> or the matching crate. The failing output is the reproduction and is kept.
Then it fixes the code, reruns the test until it passes, and runs what .github/workflows/rust.yml runs on the pinned toolchain: cargo build --workspace, cargo test --workspace, cargo clippy --tests --workspace -- -D warnings and cargo fmt --check. A change to a GraphQL type also needs ./export_schema.sh, because the workflow diffs the exported schema against schema.graphql and fails when they differ. The agent does not replace a ? with an unwrap_or_default to make a panic disappear; it returns the DomainError the caller already handles.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "A Sentry alert fired for this Rust service; its payload follows this prompt. Use the Sentry connection to read the issue, its latest event, the frames with their crate and function names, and any tracing fields on the event. Find the failing code, starting from the LDAP handler in crates/ldap/src/handler.rs and its operation modules, and the GraphQL mutations and queries in crates/graphql-server/src. Add a #[tokio::test] in the module where the neighbouring tests live, using the mock backend helpers already there, that reproduces the error. Fix the code until the test passes, then run `cargo test --workspace`, `cargo clippy --tests --workspace -- -D warnings` and `cargo fmt --check`; run ./export_schema.sh if a GraphQL type changed. Open a pull request that links the Sentry issue, quotes the frames and the failing test output, and explains the cause. Change nothing unrelated to this error.\n\nAlert payload:\n{payload}",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
],
"connections": [
"sentry"
]
}- 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 a pull request that changes one crate and adds one test in that crate's existing test module. The description links the Sentry issue, names the function and the crate, shows the test failing on the old code and passing on the new, and lists the cargo test, clippy and fmt results. When a GraphQL type changed, the diff also includes the regenerated schema.graphql.
The transcript on the session keeps the Sentry reads, every cargo command with its full output and every file the agent opened, so the -D warnings result is visible rather than reported. The run.completed webhook delivers the agent's final message as data.result and a session_url to read the rest.
A reviewer checks that the test drives the same operation Sentry saw, that an LDAP change still answers the client with the right result code instead of closing the connection, and that a fix in a mutation keeps the permission checks the handler applied before it. A follow-up message to the session, when the fix belongs in the backend handler rather than the protocol layer, moves it on the same branch.
Run it on every Sentry issue alert
Add an alert rule to the Sentry project with a webhook action and send it to a handler on your server. The handler appends the alert's JSON to this prompt and sends the request with the Sentry issue id as Idempotency-Key, so Sentry's retries find the run that already exists. Each issue gets one sandbox and one pull request.
With a webhook URL on the API key, Rush POSTs run.completed to your handler with session_url once the turn ends, and the handler can comment the pull request link on the issue. Or have that handler call a webhook trigger on an automation in the Project with this prompt: it forwards the alert's JSON as the body with the trigger's secret as Authorization: Bearer, because Sentry signs its own webhooks and cannot send that header. The body becomes the event text after the prompt, and max_runs_per_hour caps an issue that keeps firing.
The use case this job follows, with its automation and trigger: Fix a bug from an alert.
Why run it on Rush?
Reproducing a Rust panic by hand means building the workspace on the pinned toolchain, writing the mock setup for a handler you may not know, and waiting for clippy to agree. In a Rush sandbox the agent builds once on its own disk, uses the crate's existing mock helpers, and runs the same four commands the workflow runs, so the pull request arrives with the build already green.
The evidence travels with the result: a test that failed, the same test passing, and a transcript of each cargo command. Issues run in parallel, each in its own clone up to the key's max_concurrent limit, so an LDAP search bug and a GraphQL mutation bug from the same release are two small reviews instead of one long one.
Frequently asked questions
Which toolchain does the sandbox build with?
The one rust-toolchain.toml pins, 1.91.0, which is also the MSRV the workflow uses and the workspace's rust-version. The agent reads those and does not build with a newer compiler that might accept code the pinned one rejects.
Does it need an LDAP client or a database to run the test?
No. The handler tests use LdapHandler::new_for_tests with a mockall backend, so the operation runs in process. The sql-backend-handler crate's tests use SQLite through sea-orm and need nothing outside the sandbox either; the agent runs them only when the fix is there.
What if the panic is inside a dependency such as ldap3_proto or juniper?
The agent reads the frame above the dependency, the call in your crate that passed the bad value, and fixes or validates there. When no frame in your code is involved, it says so in its final message and opens no pull request, so a dependency upgrade can be decided separately.
Will it edit schema.graphql by hand?
No. It runs ./export_schema.sh, which the rust.yml workflow also checks by exporting the schema and diffing. A hand edit would drift from the code and fail that step.