An audit is not a grade. It is a forecast: an outside read of whether your system can carry a specific thing you are about to ask of it, delivered before you commit money to the answer. The video above is the full walkthrough. This is the written version, with the self-check list at the end in a form you can copy.
“Is my code good?” has no answer
There is no score. Every codebase has problems, including the ones we are proud of, so any verdict on general quality is an opinion wearing a report cover.
The question that does have an answer names a load. Ten times the traffic. An enterprise client’s security review. A due diligence. Two years of a roadmap you already sold to investors. Once the load is named, “will it hold” becomes a technical question with evidence behind it, and the same codebase can pass one audit and fail another without a line of it changing.
That is not hypothetical. A healthcare platform we work with ran well for years, then started winning enterprise clients, and enterprise clients bring their own security reviews. The code was the same on both sides of that line.
It cuts the other way too. A consumer company came to us with a mobile app and an investor-promised B2B product they wanted built on top of it. They bought an audit first. It came back with serious flags on quality, maintainability and security, so the board postponed the product it had already promised, fixed the foundation, and shipped the new line on top of it afterwards. The audit never said the code was bad. It said the code could not carry that particular product yet, which is the only reason the product exists today. (The full engagement is a case study.)
Before commissioning an audit from anyone, write the sentence: in twelve months, this system has to ___. An audit without that sentence is a general opinion with an invoice attached.
When an audit is worth buying
Three situations account for most of the audits we run, and each has a load hiding inside it.
Something already hurts. Releases are slow, things break, small changes take three times longer than they used to. Worth knowing before you start: what hurts is rarely where the problem lives. A slow checkout is usually not the checkout, it is the database underneath it or the way changes get tested before they ship.
You cannot grade the answers you are getting. You ask how long something will take, or whether the platform is safe, and the answer arrives with no way to check it. This is the most common reason and the one people are least comfortable saying out loud. It is not distrust. You cannot grade an answer you could not have produced yourself.
You have committed to something you are not certain of. The enterprise deal, the next scale milestone, the second product. The load is already named. Nothing has been measured against it, and because nothing is on fire, the cheapest moment to check is the one most companies skip.
Sometimes the audit is not your idea at all: an investor before a round, a due diligence, a certification body, or you are the buyer and cannot read the code you are about to pay for. Below roughly the mid-market line the large diligence firms are not interested, so buyers at that size tend to guess.
There are also three situations where we would tell you not to bother. If you are still searching for product-market fit, there is no load yet. If you already know the answer and want a document that agrees with you, the report will disappoint somebody. And if we cannot get access to the code, the tooling and the people, there is nothing to audit.
Lens one: can this team carry the load?
The audit starts with the process, not the code, because the codebase describes the past twelve months and the process determines the next twelve. Code can be replaced in weeks. The way a team decides, specifies, hands out and reviews work takes a year to change, which is why fixing a codebase without fixing the process just grows the same code back. A code-quality problem is very often a process problem wearing a costume.
The most expensive thing in this lens is also the least asked about: where the knowledge lives. Not who is talented, but what stops entirely if one person leaves.
In one due diligence, the entire product was running on the output of a single developer with no written contract. That is three findings, not one. Operationally, the company stops if he does. Legally, there are no terms and no notice period in either direction. And on ownership, the intellectual property had never been transferred, so the business did not own the product it was selling. None of it is visible in a code review, and in a diligence it is not an appendix item, it is the price.
Lens two: is it yours, and can it take the next shape?
This is the lens most people picture: the codebase and infrastructure read as an asset you own.
Architecture determines whether your next change is priced in days or months, and whether the system survives a traffic multiple, a second platform, or the integration you just sold.
The data layer is the expensive one, and the one nobody asks about. Code is cheap to change; three years of live records are not. If you hold personal data, this is also the first thing an enterprise security review reads.
Coding standards decide how long a new developer takes to become useful, and whether an AI agent can safely touch anything at all.
Test coverage decides whether you can change the system without gambling. Without a safety net, teams quietly stop touching the risky parts, and the risky parts are usually the valuable ones. That healthcare platform had effectively no automated tests on a system where a silent bug carries medical weight, and nobody had noticed, because nothing had broken yet.
Security posture, in the code and the infrastructure, at the level that decides whether a deal stalls in someone’s vendor review. A dedicated penetration test is a different product, and we say so when that is what you need.
AI readiness, which is two separate questions. Whether the codebase can be worked on by AI (standards, tests, documentation, structure), which sets your team’s speed for the next few years. And whether it was written by AI, quickly, with a foundation that never caught up.
Then the two nobody asks for. Licences: every project stands on other people’s code, some of it carrying terms that expect you to publish your own source in return. A package three levels deep can leave you choosing between publishing your source and rebuilding the component. Ownership: paying for code is not owning it. Contractors, agencies, an early friend who helped for a few weekends, all of it needs a written assignment, or the work may not belong to the company at all.
Both surface at the worst possible moment, which is a diligence with a buyer in the room.
Lens three: what happens when the load lands
The same system read as behaviour rather than as an artifact.
Infrastructure tends to fall over on the day the product finally works. The quieter version is end-of-life: every framework and database you build on has a date after which nobody publishes security fixes. You did not choose that date, and it is already in the calendar.
Performance is worth measuring rather than sensing. You paid to acquire the users who leave before the product gets good, so slowness means paying for the same traffic twice, while the hosting bill outgrows revenue.
Release answers the most revealing question in the audit: can you deploy to production today? If a fix has to wait for a ritual, the company cannot respond at the speed its market assumes. The healthcare platform again: an end-of-life stack, no automated pipeline, releases done by hand, and no one aware of it because nothing had forced a test.
Monitoring decides who finds out first. If you are not alerted, your customers are, and the worst case is not downtime, it is the site staying up while orders quietly fail.
What you actually receive
Every finding has four parts, in this order.
| Part | What it means |
|---|---|
| Finding | What is true about the system |
| Evidence | The artifact that proves it |
| Recommendation | What to do instead |
| Cost to act | What that will take |
The discipline matters more than the format. A finding without its artifact is an assertion, and a recommendation without a cost is not advice: “improve your test coverage” is the software equivalent of “eat healthier”, true and useless in the same breath.
The report is written to be forwarded, because it usually is. It has to hold up in front of an engineering lead who will argue with the numbers and an owner deciding in money and months, and survive being sent to an investor without a translator.
You are buying the order, not the list. Plenty of tools will hand you everything wrong with a codebase for free, and on that list everything looks urgent. The value is knowing what is first, what is next, and what you can live with for another two years.
The engagement itself is discovery, analysis, a written report and a readout call. Discovery is where the load gets named. Analysis covers the code, infrastructure and tooling, plus conversations with the team, which is where lens one comes from and is not a formality.
What to tell your developers
Not behind their backs. It always surfaces, and the finding they will remember is that you went around them.
Say what it is: not a performance review, a second pair of eyes on a system the business now depends on. The honest arithmetic is worth saying out loud to them, because it is genuinely in their favour. An audit that finds nothing is free reassurance for everyone. An audit that finds something hands them the case for the maintenance work they have probably been requesting for a year.
Occasionally the real question is whether the team can do what is coming. That is fair, and an audit can answer it: we have written reports saying the team as it stands cannot carry what is next. What an audit cannot do is start from the answer.
Five checks you can run yourself
Here is the part that costs me something to write, as somebody who sells these audits: a good share of what we do in the first days, you can now do yourself with AI.
- Write the sentence. “In twelve months, this system has to ___.” Until it exists, nobody can tell you whether your software is in trouble, including us.
- Ask for artifacts, not opinions. Where are the coding standards written down? The test cases, the release runbook, the architecture diagram? You are not grading the answers. Absence is the finding.
- Ask what stops. If this person left tomorrow, what halts entirely, as opposed to slowing down?
- Run the ownership check. Does a signed agreement exist for everyone who has ever written code for you, including the early people? And can someone produce the licence list for every package you depend on? That list is an SBOM, a software bill of materials, and every package manager generates one in minutes. Most teams have never been asked for it.
- Time the boring things. How long to onboard a developer, or a client? How long from a change being finished to it being live? That last one is lead time for changes, one of the four DORA metrics, and it says more about a company than a code review will.
AI does most of the mechanical half. Point it at the repository and ask it to produce the architecture diagram nobody ever wrote, which tells you something either way. Ask which critical paths have no test behind them. Ask for every dependency with its end-of-life date, which is usually the most alarming list a founder reads that month.
What the list cannot do for you
Three limits, and they are the reason outside eyes still earn their fee.
You cannot grade an answer you could not have produced. Your team cannot report what they do not know. And you have nothing to compare against: you have only seen how your own team works, so whatever it does is normal by definition. Every team believes its own workarounds are simply how software gets built everywhere.
Which is the whole case for doing this before it is urgent. You do not audit to find out whether your code is good. You audit so that the next expensive decision stops being a guess.