I’ve been living in Claude lately, just to get a feel for things, and the following is some of things that I’ve learned so far.
Brownfield
For this discussion, I’m calling brownfield code anything legacy, including something from six months ago that you personally wrote but don’t remember how it works, as well as anything that doesn’t have good/any unit testing.
Give AI some background on your app
To start, tell AI some things about your app, what it does, how it is used, and have it read through the code. If you have any special tools it should be aware of, like the Symfony binary or Drupal’s drush or WordPress’s WP CLI, let it know about these and possibly how to use them. If you have special ways to interact with the database, for instance if only you can run root commands for DDL, let it know, too, as well as how you want it formatted, just to save some steps in the future.
You can try adding these to an AI-specific file such as CLAUDE.md, although I’ve had varying degrees of success with this.
Unit testing
First and foremost, add unit testing. If you are using a framework like Symfony or Laravel this might be easy, however if you are vanilla PHP this might be more complicated, but don’t sweat it, let AI sweat it.
Avoid making too many, or any changes if possible, to the application, and always review the changes. Do not address bugs at this point unless they are show-stoppers for adding the testing. Your goal is to get tests to run 100% clean for the way that code is written today.
Code coverage
Next, add code coverage, and make sure the output is available for both AI to inspect, as well as for you to inspect. I know that code coverage is not necessarily a sign of the quality of an application or the code itself, but at this stage it give you a good idea of how well your code is tested.
Review the coverage report and have AI add more tests as needed. This is subjective, but at this stage the more coverage you have the more likely your future refactors will be correct.
Refactor and repeat the previous steps
You eventually might get to a point where you have large functions/methods that aren’t covered by some tests. If this happens, have AI refactor these into multiple things that can be more easily tested. Focus on one function/method at a time, and make sure AI knows that this is the plan, too.
Add logging and repeat the previous steps
If you don’t have any logging, now’s the time to add it. The goal of this logging is to allow AI to see the errors. If you skip this step you might end up with a bunch of “try it now” steps where you are hunting for errors in your developer console, server logs, etc. Your goal is to eventually let AI see the errors and correct them in a loop.
Considering additional tests
This is optional and will depend on your application. My recommendation would be to try adding one or more of these to see how problematic they are. At this point remember that these tools are not necessarily for you, they are for the AI tool to use to write better code.
Examples of other tests include PHP CS, PHPStan, Psalm and Infection. Consider adding these one at a time, probably on a dedicated branch, and see what they report. Depending on your code style some of these might not be a good fit, and that’s okay. Things like PSR and PER coding standards are just opinions and you are not required to follow them. That said, if you can use some of these tools you might find additional potential issues.
Find bugs
Once you have a stable testing environment of your existing code, you can now instruct AI to suggest changes to it. Keep it small for now still, don’t make giant sweeping changes. And make sure you understand and test all changes, too. This is not AI’s app, this is still your app and you are using AI as a tool. If you do not understand a change, ask AI why it is proposing it, don’t just blindly accept the change. DO NOT VIBE CODE A BROWNFIELD APP!
Upgrade
Once bugs are addressed I would next move on to upgrading your application’s parts. This could be PHP or libraries or frameworks or possibly the server infrastructure itself. What you are upgrading is wholly dependent on your specific application. Take baby steps here. Tell AI, where possible, to perform whatever upgrade and then run all of your tests. This is where having more tests and coverage can be helpful.
I would strongly discourage running AI as root and letting it perform server-level upgrades however. The tools are great, but whereas code can easily be rolled back, infrastructure changes can be harder to revert and sometimes even figure out what was changed.
We’re doing the upgrade now because we want all future features and bugs to be addressed against the most recent version of our dependencies.
Depending on your application, this might go very fast or might take a lot of time and effort. Don’t skip this though. Somewhere out there is a bug or security hole that was fixed in the next version of one of your dependencies. This is the time to bite the bullet and get as far up to date as you can.
Welcome to greenfield
Okay, you might not technically be greenfield, but hopefully you are familiar enough with the code (possibly for the first time, possibly once again) that you can reason about it. You can now continue to bug hunt, to add features or possibly ask AI to suggest where to go next. You can even vibe code at this point, but please stay on a dedicated branch. Whatever you do, always ask AI to add tests for whatever it is working on, and to always run tests before it considers the task complete. If you have good tests and logging, the AI should be able to loop itself until the problem is solved.
A caution on AI looping
One of the things to be careful about when having AI loop until all tests run green is that it can sometimes cheat, at least in my experience. For instance, this morning I saw AI say something to the effect of “skip the XYZ test so that everything passes”. I guess it took the “you must pass all tests” as a prime directive, and I had to stop it and tell it that it was cheating. (Us humans would never do this, right?)