How we onboard onto an existing codebase
What happens when a client brings us a system that already exists: the first-week audit, how we triage tech debt from real risk, and the principles that keep us from rewriting things that don't need rewriting.
Half of our engagements start with an existing system, not a blank repo. A founder’s MVP that outgrew its architecture. A platform built by a previous agency that nobody can deploy anymore. An internal tool that works but scares everyone who touches it. This post describes what we actually do in the first two weeks.
We don’t start by reading code
We start by running it. Can we clone the repo, install dependencies, and get a working local environment in under an hour? If not, that’s the first finding. A system that’s hard to set up locally is a system that’s hard to change safely, and changing it safely is the whole job.
The audit is a written deliverable
In the first week we produce a short written assessment covering five areas:
- Build and deploy. Can we get from commit to production, and is the path documented? Or does deployment depend on one person’s laptop?
- Test coverage and confidence. Not a coverage number, but an honest answer: if we change this module, will the tests catch a regression?
- Security surface. Auth, secrets management, data handling, dependency age. We run the same checks we’d run on our own code, aligned with our Secure SDLC Policy.
- Operational visibility. Logging, alerting, error tracking. Can we tell when something is broken before a user reports it?
- Architecture and data model. Where does state live, how does data flow, and where are the coupling points that make changes expensive?
This document is the client’s, not ours. It survives the engagement.
Triage, not a rewrite
The audit produces a list of findings. We sort them into three buckets:
- Fix now. Security vulnerabilities, broken deploys, data-loss risks. These get addressed in the first sprint regardless of the roadmap.
- Fix alongside. Tech debt that’s in the path of planned work. We clean it up as we go, not in a separate "refactoring sprint" that never gets prioritised.
- Leave alone. Code that’s ugly but working and not in scope. We document the risk and move on. Rewriting stable code to make it prettier is how budgets disappear.
The hardest part of onboarding onto a legacy system is resisting the urge to rewrite it. A rewrite is almost never the right call in the first month. You don’t understand the system well enough yet, and the client is paying for outcomes, not aesthetics.
We talk to the people, not just the code
If there’s a previous team, an internal engineer, or even a solo founder who wrote the original system, we schedule a walkthrough. Code doesn’t capture intent. Comments rot. But a 90-minute conversation with the person who built it will save weeks of archaeology.
We come with specific questions, not "tell us about the architecture." We ask: why is this service separate? What broke last? What would you change if you had three months? The answers tell us where the real risks are, not just the ones that show up in a linter.
We ship something in week one
Even during the audit phase, we try to land at least one small, visible change: a CI pipeline fix, a dependency update, a flaky test stabilised. It proves to the client that we can operate in their environment, and it proves to us that the deploy path actually works.
If we can’t ship a one-line change safely in the first week, that tells us more about the state of the system than the audit does.
Why it matters
Clients who bring us existing systems are usually nervous. The last team left, the codebase is a black box, and they don’t know how bad it is. The audit gives them an honest answer. The triage gives them a plan. And the first shipped change gives them evidence that the new team can actually operate the thing.
That’s the real deliverable in the first two weeks: not a rewrite plan, but confidence that the system is understood and under control.