What the audit is for

Not to catalogue everything wrong — that list is always long and mostly irrelevant. It is to answer three questions: can we safely change this, what will break first, and is repair cheaper than rebuilding?

Inheriting a codebase — after an acquisition, a vendor change, or a departing developer — starts with an honest assessment. Here is a structure that produces a decision rather than a document.

The seven things to assess

AreaKey questionRed flag
RunnabilityCan we build and run it locally?Nobody can, or it takes days
DeploymentCan we deploy a change safely?Manual, undocumented, or feared
TestsIs there a safety net?None, or all failing
DependenciesAre they supported and patched?Unsupported runtime versions
SecurityAny obvious exposure?Credentials in the repository
Data integrityIs the data consistent?Orphaned records, no constraints
KnowledgeCan anyone explain it?One person, or nobody

Start with runnability and deployment, not code quality. A well-written system you cannot deploy safely is more dangerous than an ugly one you can. If you cannot make a change and release it confidently, nothing else in the audit matters yet.

Week one: can we operate it?

  1. Get it running locally from a clean checkout. Time how long it takes and document every undocumented step.
  2. Make a trivial change and deploy it — a text label. This tests the entire pipeline and is the single most informative exercise in the audit.
  3. Check what monitoring exists. Would you know if it broke?
  4. Verify backups — and restore one. A backup nobody has restored is a hope.
  5. Inventory the infrastructure — what is running, where, and who pays for it.
  6. Confirm you control the accounts — domain, hosting, repository, third-party services.

The label-change deployment is the best hour you will spend. It reveals whether there is a pipeline, whether tests run, whether staging exists, whether anyone is afraid, and how long the loop takes. Teams that skip it discover all of this later, under pressure.

Week two: what will break first?

  • Dependency audit — unsupported runtime or framework versions are a deadline, not a preference.
  • Known vulnerabilities in dependencies, via a standard scanner.
  • Credentials in the codebase or in commit history.
  • Data model integrity — missing constraints, orphaned records, inconsistent state.
  • Error rates and log noise — what is already failing that nobody noticed.
  • Performance under real load, not on an empty local database.
  • Single points of failure — one server, one credential, one person.

Prioritising what you found

The list will be long. Order it by risk, not by irritation:

PriorityCategoryExamples
ImmediateSecurity and data lossExposed credentials, no working backups
UrgentOperational riskCannot deploy safely, no monitoring
ImportantApproaching deadlinesUnsupported runtime, expiring dependencies
PlannedChange velocityMissing tests, tangled modules
OptionalAestheticsInconsistent style, dated patterns

Resist starting with the code that annoys you most. It is rarely the code that will hurt you first — and rewriting it consumes the time you needed for the backup that does not work.

The rebuild question

Rebuilds are proposed more often than they are justified. The honest test:

Not sufficient reason

  • The code is ugly or dated
  • It uses a framework you dislike
  • You did not write it
  • It has no tests
  • A rewrite feels faster than understanding it

Genuine reason

  • Runtime or framework is unsupportable
  • Every change breaks something unrelated
  • Business requirements changed fundamentally
  • Security cannot be remediated in place
  • It cannot scale to committed requirements

Rewrites usually take longer than estimated and lose behaviour nobody documented. The existing system encodes years of edge cases and business rules that exist nowhere else. Incremental replacement — strangling the old system module by module while it keeps running — is slower to feel satisfying and far more likely to succeed.

The output of the audit

A short document, not a comprehensive one:

  • Can we operate it safely today? Yes or no, with specifics.
  • The prioritised risk list, with the top three named.
  • An estimate for stabilising — the immediate and urgent items only.
  • A recommendation: repair, incremental refactor, or rebuild.
  • What we still do not know, and what it would take to find out.

Inherited a codebase and unsure what you are holding? Tell us what you know about it — we do audits and take over inherited systems. See our web application service and rescuing a failed project.

Frequently asked questions

One to two weeks for a moderate codebase. Longer than that and you are rewriting rather than assessing. The goal is a decision — fix, refactor incrementally, or rebuild — not a complete understanding of every file.
Rarely, and less often than teams believe. Rewrites are justified when the technology is unsupportable, when nobody can safely change the code, or when the business requirements have changed fundamentally. "It is ugly" is not sufficient.
Assume they are. Most inherited codebases arrive without their authors. That is why the audit focuses on what you can determine from the code, the running system and the data — not on documentation that probably does not exist.