How to Audit a Codebase You Inherited
Inherited a codebase you did not write? Here is the exact order I audit an unfamiliar repo to find risk fast, before I commit to owning or changing it.
When you inherit a codebase you did not write, audit it in this order: read the entry points, map the data model, find the churn, check the tests, then read the three riskiest files by hand. Do that before you change a single line, before you promise a timeline, and definitely before you tell anyone it will be easy. Every painful project I have taken on started with skipping this and trusting a demo.
I inherit codebases constantly. Acquisitions, contractor handoffs, ventures I take over mid-flight. The method below is what keeps me from signing up for a swamp.
Start with the entry points, not the file tree
Do not open the repo and start scrolling. That teaches you nothing except that there are a lot of files. Find where the program actually starts. The main server file, the route definitions, the job scheduler, the CLI commands. These tell you what the software does, in the order it does it.
From the entry points you can trace real paths. A request comes in here, hits this handler, touches this model, writes to this table. Follow two or three of these end to end. In an hour you understand more than a week of random reading gives you, because you learned the shape of the thing instead of memorizing trivia.
Map the data model before you judge the code
The database schema is the truest document in any repo. Code lies, comments rot, but the schema is what the business actually runs on. Pull the migrations or dump the schema and read it like a story.
Look for the tells. Columns named temp or new or data2. Tables with no foreign keys where there obviously should be. A users table with 60 columns because nobody ever said no. The schema tells you where the team cut corners under pressure, and those corners are where your future outages live. This matters more than any style question, which is why I treat the data model as the backbone of scoring a repository I did not write.
Find the churn to find the risk
Git history is a heat map of pain. Run a churn analysis: which files changed most often in the last year, and which changed most often alongside bug fixes. That small set of files is your real liability. It is where the requirements were unclear, the design was weak, or the code fought back every time someone touched it.
A file edited 200 times is telling you something. Either it is a genuine hub, in which case its quality matters enormously, or it is a design mistake that everyone keeps patching instead of fixing. Either way, that is where your audit attention belongs, not spread evenly across a thousand files that never change. I automate this with ReformCode so churn and risk surface in minutes instead of an afternoon of git spelunking.
Check whether the tests actually test anything
Do not trust a coverage number. Open the tests and read them. Are there assertions, or do they just call the function and check it did not throw. Do they cover the money paths and the auth paths, or only the easy pure functions. Run them and then intentionally break something real to see if they catch it.
Tests that pass while the code is broken are worse than no tests, because they sell false confidence. A codebase with honest, loud tests around its critical paths is one you can change safely. A codebase with green checkmarks and no teeth is a trap. This distinction is the whole difference between a demo and something shippable.
Read the three riskiest files by hand
Now, and only now, do you read code closely. Take the intersection of your churn list and your risk map, pick the top three files, and read every line. This is where the score stops and judgment starts.
You are looking for intent. Can you tell what this file is supposed to do. Is the mess load-bearing or just ugly. Is the coupling accidental or fundamental. Thirty minutes per file tells you whether the whole codebase is salvageable or whether you are looking at a rewrite wearing a maintenance costume.
Turn the audit into a decision
An audit that ends in a vague feeling is a waste. End it in a call. Own it as is, own it with a scoped cleanup, or walk away. Write down the three biggest risks and what each would cost to fix. That document is worth more than any dashboard, because it converts fear into numbers someone can act on.
I run this exact sequence every time I fold a new venture into the operator's stack. The repos that pass get built on. The ones that fail get a hard conversation before I commit a dime. Auditing inherited code is not about finding perfection. It is about knowing exactly what you are agreeing to own.