Why Audit

7 Warning Signs Your Codebase Needs an Audit

Codebases rarely fail suddenly. They degrade in ways that everyone on the team half-notices and nobody escalates, because each individual symptom has a plausible local excuse. The estimate slipped because the ticket was underspecified. The deploy broke because of a one-off edge case. Sure.

The pattern only becomes visible when you list the symptoms side by side. Here are the seven we see most often. If three or more sound familiar, your codebase is telling you something.

1. Estimates have quietly doubled

Not on one feature. Across the board. Work that took the team a week a year ago now takes two or three, and the features aren’t fundamentally harder.

This is the classic signature of accumulated coupling: changes that should be local now ripple through the system, and every ticket carries hidden integration work. Individual engineers experience it as “I keep getting surprised by side effects.” Management experiences it as roadmap slippage with no single explanation.

The tell that distinguishes this from ordinary complexity growth: ask an engineer why the last estimate was wrong. If the answer is a shrug or “the code over there is weird,” rather than a specific, nameable cause, the weirdness is systemic. That compounding slowdown has a price tag, which we itemize in the real cost of unaudited code.

2. Only one person can touch certain areas

Every team has specialists. That’s fine. The warning sign is when specialization hardens into exclusivity: billing changes wait for Dana, deploys wait for Marcus, and when either is on vacation, that part of the roadmap simply pauses.

This is a bus factor of one, and it’s a code problem as much as a people problem: code that only its author can safely modify is, by definition, unmaintainable code. The audit-relevant question isn’t “is Dana good?” (she probably is) but “what happens in the two weeks after Dana resigns?”

A quick self-test: git shortlog -sn -- src/billing/ (or your equivalent). If one name owns 90%+ of a business-critical module, you’ve found your landmine.

3. Deploys are events, not routine

Healthy teams deploy without ceremony: small changes, automated pipeline, easy rollback. If your deploys instead involve a checklist that lives in someone’s head, a preferred day of the week, a person who “does the deploy,” or a collective breath-hold in Slack, the deployment process is compensating for something: missing tests, snowflake infrastructure, or changes so large that each release is a gamble.

The cruel feedback loop: scary deploys make teams batch changes, bigger batches make deploys scarier. Left alone, this converges on quarterly releases and permanent fear.

4. Nobody trusts the tests

Symptoms, in increasing order of severity:

  • Tests exist but the suite is slow enough that people skip it locally.
  • Tests fail intermittently and the team has normalized re-running CI until green.
  • Tests pass, but everyone still manually verifies changes, because the tests have missed real regressions before.
  • The tests were largely written against mocks of the system rather than the system, and assert that the mocks behave like the mocks.

A test suite the team doesn’t trust is worse than no suite: it costs CI minutes and provides false confidence in exactly the moments confidence matters. An auditor doesn’t just measure coverage percentage (a famously gameable number); they read the tests on critical paths and ask whether a genuine bug there would actually get caught.

5. Your dependency tree is a time capsule

Open your lockfile’s git history. If it hasn’t meaningfully changed in a year, your application is accumulating known vulnerabilities at the industry’s publication rate. CVEs don’t check whether you’re paying attention.

Related signs:

  • Upgrading anything requires upgrading everything, so nobody upgrades anything.
  • You’re pinned to an EOL runtime (a Node, Python, or framework major version past its security-support window).
  • There’s a fork of some library in the repo, patched by someone who left, for reasons undocumented.

Dependency neglect is uniquely dangerous because it’s invisible until it isn’t: the code didn’t change, but its risk profile did.

6. The same bugs keep coming back

Regression recidivism (a bug gets fixed, and a cousin of it reappears two months later in a nearby code path) means fixes are being applied at the symptom level because the underlying structure makes the class of bug easy to write. Common versions: validation duplicated (differently) in multiple places, timezone handling scattered ad hoc, permission checks copy-pasted per endpoint with local mutations.

Bug trackers make this measurable. If you tag regressions and the tag keeps growing, the codebase is generating bugs faster than tickets can retire them.

7. You inherited the code and nobody’s really read it

This one is less a symptom than a situation, but it’s the most common audit trigger we see. The agency handed over the repo. The technical co-founder left. The acquisition closed. The AI coding tools shipped six months of features in six weeks, and the humans reviewed… most of it, probably.

In all these cases you own code that no current team member deeply understands, and you’re making business decisions (hiring plans, roadmap commitments, security attestations) on top of assumptions nobody has verified. AI-assisted development deserves special mention here: the code volume is real, the review debt is realer, and we’ve written about the failure modes in hidden debt in AI-generated code.

If you don’t know what you own, an audit is how you find out.

What to do with a “yes”

If you recognized your team above, resist the two reflexive responses: panic (it’s almost never as bad as the worst fear) and the grand rewrite (it’s almost always worse than the disease). The useful move is smaller: get an independent, specific, prioritized read on what’s actually there.

Timing matters too: an audit lands differently at seed stage versus pre-acquisition, and we break down the scenarios in when to get a code audit. But as a rule of thumb: the right time is before the symptom becomes an incident, and three warning signs is before.

Get a free code audit

Webisoft offers exactly this independent read, free. A Webisoft engineer manually reviews your repository (architecture, security, dependencies, the critical paths) and sends you a written report of findings, ranked by severity, with concrete evidence. No cost, no obligation; it’s lead generation for us and a real audit for you, and both of those things can be true at once.

Get a free code audit. Worst case, you confirm things are fine. That’s worth knowing too.

FAQ

Frequently asked questions

How many of these warning signs justify getting an audit?

Three or more is the rule of thumb in the article, and the right time is before a symptom becomes an incident. One sign usually has a plausible local excuse; three side by side is a pattern, and patterns do not fix themselves.

Is a full rewrite a reasonable response if several signs apply?

Almost never. The grand rewrite is usually worse than the disease: it freezes the roadmap, rediscovers old edge cases the hard way, and often recreates the same structural problems in a new language. The smaller, more useful move is an independent, specific, prioritized read of what is actually there, then targeted fixes.

How do I check our bus factor quickly?

Run git shortlog -sn against a business-critical module such as billing. If one name owns 90%+ of the commits, you have found a single point of failure with a two-week notice period. The question is not whether that person is good, but what happens in the two weeks after they resign.

Why is a test suite nobody trusts worse than having no tests?

Because it costs CI minutes and provides false confidence at exactly the moments confidence matters, while everyone still verifies changes by hand anyway. Suites built mostly against mocks assert that the mocks behave like the mocks, and coverage percentage is a famously gameable number. What matters is whether a genuine bug on a critical path would actually get caught.

We inherited a codebase from an agency and nobody has really read it. Where do we start?

Start by finding out what you own before you make hiring plans, roadmap commitments, or security attestations on top of it. An independent review is the fastest way to convert unverified assumptions into a ranked list of facts. Webisoft's free audit does exactly this: an engineer manually reads the repository and emails a written, severity-ranked findings report within a few business days.

Free · no strings shown later

Get your free code audit

A repo URL and two minutes of your time. A Webisoft engineer sends back written findings (security, tech debt, performance) with file-and-line specifics.

Request my free audit