On April 21, hotfix/x.y.1 and hotfix/x.y.2 both merged back into develop. Same day. That is rarely a good sign.

Three tickets covered customer-facing failures across registration, schedule management, and package deploys. They had no obvious connection. It looked like one bug but was three in a trench coat, presenting as a single person.

Payments landed, registrations stayed Unconfirmed

The first ticket was a PayPal IPN bug. The money was arriving, but registrations stayed in Unconfirmed status and showed as pending. Nobody was complaining loudly enough, which makes it the most dangerous kind of data problem.

The fix had two parts. First, the inbound IPN handler had to repair the status automatically on any successful payment, so future payments self-heal. Second, production already held a pile of stranded rows with the wrong status. Those needed a bulk cleanup tool with an admin interface, a confirmation step, and a dry-run mode to walk back the damage.

The second part matters. A change that only addresses the forward path leaves the bad rows sitting in production untouched, so it doesn’t fix the problem.

”Bulk delete doesn’t work” was a scope bug

The second ticket arrived as “bulk delete doesn’t work from org accounts.” We thought it was a permissions bug. It was not.

The code called the server-side delete endpoint with an org-level scope. The endpoint does not accept that. It expects a scope below the org level. The code was supposed to walk the org’s child nodes down to the child scope before making the call, and it never did. Every bulk delete from an org context was silently wrong, and it just did nothing.

The symptom hides the shape of the problem. “Delete doesn’t work” is what the user reports. “We never resolved the scope correctly for this caller class” is what the code shows. Those are different bugs with different fixes and different test coverage requirements.

Claude did the codebase archaeology. The legacy application is old. We had to find where the org-node collection was built, trace the call path to the delete endpoint, and confirm which scope fields the endpoint actually validated. That is twenty minutes of careful reading or two hours of guessing. The agent did the reading and we checked the model.

The deploy would have re-broken it

The third ticket was subtler. Package deploys referenced assets through raw /src paths in the legacy application. That meant any in-flight edit during a deploy could touch a live customer mid-page-load. The fix was to compile dated copies of the JS and CSS, then point the references at those versioned files instead of the source tree.

A logic fix alone leaves the bug exposed while the conditions that produced it are still in place, so it isn’t really fixed until the deploy mechanics can no longer reintroduce it. We have made this mistake before in other forms. This was the version of it for assets.

Where the pairing paid off

Most AI coding demos show a greenfield project with a clean schema, a clear spec and no legacy. The agent writes the scaffold, you fill in the business logic, you ship. This was a different kind of day.

It was branch juggling across a multi-repo codebase with long-lived parallel environments, in legacy application files that have been accumulating edge cases. Two hotfix branches merged one after the other. We switched context between a data-repair problem, a scope-resolution problem, and a deploy-hygiene problem, and none of them shared any code.

The agent was most useful on the exhausting problem rather than the elegant one. It held context across the branch topology, surfaced the exact file and line that mattered, tracked which fixes touched which repo, and treated three unrelated bugs as three.

We still carry the mental model. The agent does not know that the org-scope caller has always been slightly wrong, or that the PayPal IPN handler has a history of silent failures, or that the asset pipeline has been sloppy since the last deploy refactor. That knowledge does not compress. With the agent handling the legwork, though, a day that used to cost a full day of context thrash plus a vague worry that something was missed came in around half a day, with a file-and-line trail for every fix.

None of the three was done until the forward path, the stranded data, and the deploy conditions were all handled. So when a fix ships, check all three. Check each ticket on its own, since one customer complaint can hide several unrelated bugs. And ask for the file-and-line trail so the work can be reviewed.