Skip to main content
GullySystem

How to Audit an Undocumented Codebase

By Ganesh HS, Strategy and Technology, GullySystem

Auditing an undocumented codebase means confirming authorised access, reproducing it in an isolated environment, mapping its frameworks and entry points, tracing how data and deployment actually work, and rating its risks and test coverage — then producing a readable system map and a prioritised backlog, not just a list of complaints.

Confirm Authorisation and Set Up an Isolated Environment

An audit should start the same way a takeover does: confirm who has the authority to review the code, and get it running in an environment that is isolated from whatever is currently in production. Reviewing code by reading it alone misses a lot; running it, even with dummy data, reveals behaviour that static reading cannot — which features actually work, which throw silent errors, and which pieces of the interface lead nowhere.

Imagine a manufacturer that inherited a decade-old shop-floor scheduling tool, originally built in-house by an engineer who has since retired. Before anyone reviews a single line of that tool's code, the sensible first step is standing up a copy on a separate machine or staging server, using a snapshot of real, anonymised data, so the audit can poke at the running system without any risk to the production schedule the shop floor depends on every day.

Map the Frameworks, Dependencies and Entry Points

With a running copy available, map what the application is actually built on: the language and framework versions in use, every third-party library it depends on, and each entry point — web routes, scheduled jobs, background workers, any place execution begins. Undocumented systems frequently accumulate entry points no one remembers exists, like a forgotten scheduled task that still runs nightly.

This mapping does not need special tooling to start — dependency manifests, a directory listing of the codebase, and a look at what scheduled jobs the server runs will surface most of it quickly. What this step produces is the skeleton the rest of the audit hangs off: a list of what exists before judging whether it is any good.

Reconstruct How Data, Builds and Deployment Actually Work

Data flow is usually the least documented part of any inherited system, and the most important to reconstruct: where does data enter, where is it stored, what transforms it along the way, and where does it leave — to a report, an export, another system. Tracing this by following the code, or by watching database queries while using the running copy, is slower than reading a diagram, but it is often the only option available.

Alongside data flow, reconstruct how the application is actually built and deployed: what commands turn source code into a running application, what the deployment process looks like, and whether that process is documented anywhere or exists only as tribal knowledge in whoever last touched the server. An audit that stops at the code and never establishes how deployment works leaves the most operationally risky gap unexamined.

Assess Risk, Test Coverage and Maintainability

Once the shape of the system is clear, assess it for risk: known vulnerabilities in outdated dependencies, hardcoded credentials sitting in the code, and any component that depends on a technology past its own vendor's support window. Test coverage, or its absence, is a separate but related signal: a codebase with no automated tests is not necessarily broken, but every future change to it carries more risk than a change to a codebase where tests exist to catch a mistake.

Maintainability is the final piece: how consistent is the code style, how tangled are the dependencies between modules, and how much of the system would a new developer need to understand before making a safe change. None of these need a precise score — a rough high, medium or low rating against each area is usually enough to inform what comes next.

Produce a System Map and a Remediation Backlog

The audit's real output is not a pile of findings — it is a system map a non-original developer can actually use: the framework and dependency list, the entry points, the data flows, and the deployment process, written down in one place for the first time. Alongside it, a remediation backlog, ranked by risk and business impact, turns the findings into a plan rather than a list of complaints.

This map and backlog become the reference document for every future decision about the system — whether to repair, modernise or rebuild it, how urgently, and in what order — replacing whatever tribal knowledge the system previously depended on.

Recovered architecture and dependency map

A template for documenting an inherited system's framework and dependency versions, its entry points and scheduled jobs, its data flow from input to storage to output, and its deployment process — the reference document an audit should leave behind.

Frequently asked questions

Can code be reviewed without running it?

Partially. Reading the code surfaces structure, obvious risks and style, but running it — even with test data in an isolated environment — reveals actual behaviour that static reading misses, including silent failures and dead code paths that look functional on the page but are never actually reached.

What should the audit deliver?

A readable system map covering the frameworks and dependencies in use, the application's entry points, how data flows through it, how it is built and deployed, and a prioritised backlog of risks and remediation work — not just a narrative report describing problems without a way to act on them.

Next step

Have a specific situation to work through?

This article covers the general case. Tell us what you're actually dealing with and we'll respond directly.

Discuss Your Requirement