We watch your Sentry & file the fix while you sleep. Then we stay on the pull request until it is green.
A per-issue fixer's unit of work is the Sentry issue, and its job ends at the pull request. Ours is the pull request that lands: we open the fix, watch its checks, fix what fails, round by round, and hand you a green PR to merge. Nothing merges without you.
Measured over the last 30 days, across every repository Cooper&Wright watches. See all the numbers.
Three loops. & one GitHub App.
Install once, then turn each loop on per repository. Every loop has a place where it stops and hands the work back to you.
Sentry fixes
- Watches
- A Sentry project, mapped to a repository and a stack — the errors it catches, and, where you ask for it, the performance problems it detects without one.
- Does
- Pulls the files in the trace, generates a fix with Claude, opens the pull request. Then it watches that PR's checks and fixes its own failures, round by round.
- Stops
- After three rounds it hands off, with the reason written on the row and an email to you. The merge is yours.
PR failure monitoring
- Watches
- The pull requests people open in a repository you flag, with or without a Sentry project.
- Does
- When a required check fails, the same fix rounds, pushed to that PR's own branch, with an email for each push.
- Stops
- Three rounds, then a hand-off. It never merges a person's PR.
Dependabot auto-merge
- Watches
- Dependabot's pull requests in a repository you flag.
- Does
- Fixes their CI, resolves their merge conflicts, and merges each one once every check is green, behind the merge gate you choose: every check, or the required ones.
- Stops
- A lockfile conflict goes to a person. These are the only merges Cooper ever makes, and only where you turned them on.
From the error & to your merge.
The arc of one incident, as its own page shows it: the error, the PR, a red check, Cooper's round, green, your merge, and the lesson it wrote. Representative data, invented for this page.
NoMethodError: undefined method 'full_name' for nil · app/models/user.rb:23
app/models/user.rb · self-check passed: ruby -c, no diff or conflict markers
#482 · cooper-and-wright/fix-inc-a1b2c3d4
test/models/user_test.rb:41 · expected "Anonymous", got nil
app/models/user.rb, test/models/user_test.rb · self-check passed: ruby -c on 2 files, no diff or conflict markers, 1 lesson pattern
by @maria, with one commit of hers on top of Cooper's
Guard a missing profile in Profile#display_name, not at each caller.
Cooper guarded the caller; she fixed the source. The difference is the lesson.
Every step above is a row on the incident's page. The times are representative.
Not every bug & raises.
Sentry finds an N+1 query by watching spans, not by catching an exception. There is no stack trace on a report like that and there never will be, so Cooper reads what the report actually holds: the same span evidence you read in Sentry.
SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2
Detected in OrdersController#index — the parent span, the preceding span, the query repeating twelve times, and the pattern it repeats in.
No frame named a file, so Cooper starts from the transaction: the controller the problem was detected in, and the code path it runs.
- What it fixes
- The cause of the repetition or the slowness — eager-load the association the loop reloads, hoist the query out of the iteration, select the columns actually used.
- What it will not do
- Paper over it with caching, pagination, or a background job. The records returned, and their order, must come back exactly as before.
- When it refuses
- If it cannot find the offending call site, or cannot make it faster without changing what the code returns, it says so and stops. An unnecessary query costs less than a wrong answer served quickly.
- Off until you ask
- A performance fix rewrites a query in code that works, which is a different bargain from guarding code that is already throwing. Turn it on per repository.
It learns & from you.
When a person fixes what Cooper could not, or closes its PR and ships something else, Cooper reads that diff against its own and writes a rule. The rule rides into its next fixes.
Guard a missing profile in Profile#display_name, not at each caller.
Cooper added a nil guard where the error was raised; the person changed the method that produced the nil, so every caller was fixed at once.
A lesson with a pattern is also a gate: Cooper's next patch is checked against it before it is pushed.
- Repository
- Where every lesson starts. The rule is carried into each later fix in the repository that taught it.
- Stack
- A second repository on the same stack teaches the same rule, and it is promoted to every Rails, or Laravel, or FastAPI repository you run.
- System
- Taught again on another stack, it becomes a house rule for everything you run.
- Mute
- A rule you disagree with is never injected again, and never promoted. You can watch them accumulate on the Lessons tab.
It is its own & first customer.
Cooper is mapped to its own repository. It reads one corner of its own codebase at a time, picked at random, files what it finds as an issue, and then builds it — through the same fix rounds, the same self-check and the same pull request it would open for you. Nothing merges without a green suite.
Reflect
- Reads
- One area of its own source, rolled at random so no corner is permanently ignored.
- Writes
- A GitHub issue, checked against every issue ever filed — not just the open ones — so it cannot propose the same thing twice.
Build
- Does
- Takes the oldest buildable issue and opens a pull request for it, then fixes that PR's own failing checks, round by round.
- Stops
- Three rounds an issue, then it moves on and says why on the issue itself. The state is written back as labels, so the ledger is visible to anyone reading the repository.
Publish
- Shows
- Every self-improvement that actually merged, newest first, each one a link to the pull request that did it.
- Leaves out
- A round that refused, a patch the self-check rejected, a branch nobody shipped. Only merges reach the page.
How is this different from Sentry's Seer?
Seer finds the root cause of a Sentry issue and opens a fix PR for it, inside Sentry, one issue at a time, and it is good at it. Cooper&Wright starts where that ends. Its unit of work is the pull request, and it covers the pull requests Seer never sees: the ones people open, and Dependabot's.
- Unit of work
- A Sentry issue.
- A pull request that lands.
- Where it runs
- Inside Sentry.
- On GitHub, as an App, on the PR and its checks.
- Ends at
- A fix PR.
- A green PR you merge, or a bounded hand-off with the reason.
- Pull requests it sees
- The ones it opens.
- Those, the ones people open, and Dependabot's.
- When you overrule it
- The issue is closed.
- It reads your fix against its own and keeps the rule.
We run it & on itself.
The repository Cooper&Wright lives in is watched by Cooper&Wright: its Sentry project is mapped, its pull requests are monitored, its Dependabot PRs are merged by it. The lessons it holds today came from its own mistakes. There are no customer quotes on this page yet, no logos, and no numbers we did not measure.
The stack is read from the repository's own manifests and shown beside your setting. If yours is on the list, sign in and let it watch a repository of yours.
Free & in beta.
Every loop, every repository you connect, for as long as the beta runs. The tiers beneath are what it becomes.
No card. Sentry fixes, PR failure monitoring and Dependabot auto-merge, on as many repositories as you connect. Paid plans are what it becomes, and beta testers will hear from us before anything changes.
10 pull requests seen through a month · 1 repository · no card
Unlimited pull requests · 3 repositories · PR monitoring and Dependabot auto-merge
Unlimited pull requests · 10 repositories · team dashboard and shared lessons
Common questions
Does it merge automatically?
Dependabot's PRs, yes, once every check is green, behind the merge gate you choose, and only in a repository where you turned auto-merge on. A Sentry fix or a PR a person opened waits for you unless you turn on its own auto-merge switch for that repository. Both are off by default.
What if the fix is wrong?
Close the PR, or push your own commit over it. Cooper learns from what you ship instead: it reads your fix against its own and distils a rule it carries into its next fixes. If its own PR's checks fail, it tries three rounds, then hands off with the reason on the row.
What does it read, and what does it write?
It starts from the files in the trace's in-app frames, then reads whatever it asks for through two read-only tools, read_file and list_directory, while it works. It writes only to its own PR branch, or to the branch of a PR you asked it to watch. The one exception is Dependabot: to make Dependabot rebase a conflicted PR, Cooper commits a comment to dependabot.yml on the default branch, marked [skip ci], at most once per PR.
Which stacks?
Rails, Laravel and FastAPI first. Flutter and Dart, Go, JavaScript and Rust are in beta. The stack is read from the repository's own manifests and shown beside your setting, so a wrong choice is caught rather than guessed at.
What happens after three failed rounds?
The PR is marked as needing attention, the reason is written on its row, and you get an email. Nothing is pushed again until you press Retry, which gives it a fresh budget of three.
Is self-hosted available?
Cloud only. Cooper&Wright is a GitHub App and a Sentry integration; there is nothing to run on your side.