Use case

Taking over software after the person who built it left

The system runs the business, the person who wrote it has gone, and nobody can safely change anything. The first job is not rewriting it — it is finding out what it does.

The situation

A business depends on a system — an internal application, a set of scripts, an elaborate integration — that was built by one person over several years. That person has left, retired, fallen out with the company, or simply moved on to other work. Nothing was documented, because documentation is what you write for someone else and there was never anyone else.

It still works, which is the deceptive part. The business carries on and the problem is invisible until something needs to change: a supplier changes a file format, a tax rate moves, a certificate expires, a dependency stops being supported. Then there is no one who can make the change safely, and the options all look expensive.

This situation is more common than it appears in any survey, because businesses do not advertise it. It is also frequently misdiagnosed as a technology problem when it is a knowledge problem: the code is usually comprehensible, and what is missing is the reasoning behind it.

How it shows up

Symptom, cause and change

The most expensive mistake in this situation is treating a symptom as a diagnosis. These are the three columns kept apart.

Symptom, cause and change Each row reads left to right: what you notice, what is actually causing it, and what changes once it is addressed. Symptom Actual cause What changes Nobody can say with confidencewhat the system does end to end. It was never meant to last The immediate risk is closed Changes are avoided rather thanmade, and workarounds accumulatearound the system instead. One person could hold it intheir head Changes become possible again There is no test environment, orthere is one and nobody knowswhether it matches production. No second pair of eyes The knowledge exists outside onehead Deployment is a manual sequencesomebody half-remembers. Success hid the risk The replace decision is informed
Each row reads left to right: what you notice, what is actually causing it, and what changes once it is addressed.

Why it happens

It was never meant to last
It solved an urgent problem quickly and then became load-bearing without anyone deciding it should be.
One person could hold it in their head
Documentation has no immediate payoff when the only reader is the author, so it never got written.
No second pair of eyes
Without review or handover there was never a moment that forced the reasoning to be made explicit.
Success hid the risk
A system that runs reliably for years generates no signal that it is a single point of failure.
The departure was not planned for
Even an orderly exit rarely includes the weeks required to transfer this kind of knowledge properly.

How we approach it

  1. Establish what would happen if it stopped

    Before anything else: where does it run, who can access it, is there a backup, has anyone ever restored one, and what breaks in the business if it is unavailable for a day. This is a few hours of work and it is the only part that is genuinely urgent, because everything else can wait and this cannot.

  2. Map the boundaries

    What goes in, what comes out, what it talks to and on what schedule. Inputs and outputs are observable without understanding the internals, and they give you an accurate picture of the system's role in the business considerably faster than reading the code does.

  3. Get it into version control and a repeatable deployment

    If the running code is the only copy, that is the first thing to fix. Version control, a documented build, and the ability to stand the system up somewhere else are the foundations of every subsequent decision, and they can be done without understanding what any of it means.

  4. Write characterisation tests

    Rather than testing what the system should do — which nobody knows — record what it currently does for a representative set of inputs. Those become a safety net: any future change that alters the recorded behaviour is flagged, even where nobody can say whether the original behaviour was correct.

  5. Document the reasoning, not the code

    The code says what happens. What is missing is why: why this exception exists, why this customer is handled differently, why this step runs at 4am. Much of that can be reconstructed by asking the people who use the system rather than by reading it, and that reconstruction is the actual deliverable.

  6. Then decide, with evidence

    Only at this point is the keep-or-replace question answerable. A stabilised, documented, tested system is frequently worth keeping for years; the same system before this work looks like it must be replaced urgently, and that impression is usually wrong.

What changes

The immediate risk is closed
Backups verified by an actual restore, access held by more than one person, and a known answer to what happens if the machine fails.
Changes become possible again
A safety net and a repeatable deployment mean a required change is a task rather than a crisis.
The knowledge exists outside one head
Written reasoning, not just code, so the next handover does not repeat this.
The replace decision is informed
Made against a documented understanding rather than against fear of the unknown.
Dependency upgrades stop being unthinkable
With tests in place, the upgrade that has been deferred for four years becomes a bounded piece of work.
The business stops routing around it
Workarounds built to avoid touching the system can be retired once touching it is safe.

Where it goes wrong

The most expensive mistake is deciding to rewrite before understanding. A rewrite of an undocumented system reproduces the bugs you knew about and loses the behaviours you did not, and those lost behaviours are usually the ones handling the exceptions that keep a specific customer happy.

The second is treating the code as the specification. Code shows what happens, not what was intended, and a faithful rewrite will faithfully reproduce mistakes that were never noticed.

The third is trying to understand everything before doing anything. Full comprehension is not achievable and not necessary; stabilisation, boundaries and tests deliver most of the risk reduction long before anyone understands the whole thing.

The fourth is skipping the restore test. An untested backup is an assumption, and this is precisely the situation where assumptions have never been checked.

The fifth is losing the people who use it. They hold much of the missing reasoning, and once they leave too, reconstruction gets considerably harder.

The sixth is doing this work and not writing it down, which produces the same situation again with a different name on it.

What else you could do instead

Stabilising is not the only option and it is worth comparing honestly against the alternatives before committing.

Rehire the original author as a contractor
If they are available and willing, this is frequently the cheapest route to the reasoning. It is a knowledge transfer engagement rather than a development one, and it should be scoped that way with documentation as the deliverable.
Replace it with a product
Sometimes the system does something a product now handles well, and the years since it was built have changed the market. Worth checking properly before assuming a custom replacement is needed.
Leave it and manage the risk
Legitimate if the system is genuinely stable, the dependencies are supported, backups are verified and nothing is likely to force a change. The risk is that this is asserted rather than checked.
Rewrite from scratch
The most commonly chosen and most commonly regretted. It becomes reasonable only once the behaviours are documented and tested, which is the same work as stabilising — so stabilising first loses nothing.

How we would know it worked

Before anything changes, record whether a backup has ever been successfully restored, how many people can deploy a change, and how long the last required change took to make — or how long it has been deferred.

During the work, the useful measure is coverage of the boundaries: what proportion of inputs, outputs and scheduled jobs are documented and characterised by tests.

Afterwards, the measure that matters is time to make a small change safely. If a tax rate update still takes three weeks and a nervous conversation, the stabilisation has not finished.

How long it takes and what it costs

The urgent portion — access, backups, a verified restore, knowing where it runs — is usually a matter of days and should not wait for a wider engagement.

Boundaries, version control, repeatable deployment and a first set of characterisation tests typically runs four to ten weeks depending on the size of the system and how much of it is genuinely in use.

Documenting reasoning continues alongside and is never entirely finished. The point at which it is enough is when a competent developer who has never seen the system can make a change without asking anyone.

Estimates are labelled as estimates. Timelines here are planning ranges from comparable work, not commitments, and not measured client outcomes. We quote against a defined scope after a discovery call.

Services involved

Questions

Should we just rewrite it?

Not before it is documented and characterised, because a rewrite of a system nobody understands reproduces the bugs you know about and loses the exception handling you do not. The work required to make a rewrite safe is the same work as stabilising, so stabilising first costs nothing and frequently changes the decision.

What is genuinely urgent here?

Access, backups and a verified restore. Everything else can wait weeks; those cannot, because the failure mode is losing the system entirely rather than merely being unable to change it.

Can you work with code in an unfamiliar language?

Usually, and we would say plainly if not. Older business systems turn up in a wide range of technologies and the stabilisation work — boundaries, deployment, characterisation tests — is largely language-independent. Where the specific stack needs a specialist, we would bring one in rather than improvise.

The original developer is still contactable. Is that useful?

Extremely, and it is frequently the cheapest option available. Engage them for knowledge transfer with documentation as the deliverable rather than for development work, and do it before the relationship or their memory fades further.

How do we stop this happening again?

Documented reasoning rather than only code, more than one person able to deploy, dependencies kept current rather than frozen, and a written handover requirement for anyone who builds something the business depends on. None of it is expensive relative to the situation it prevents.

What if the system has no test environment?

Creating one is part of the early work and is usually possible once deployment is repeatable. Until it exists, changes are being made directly against production, which is the state that makes every required change feel like a crisis.

Is it worth upgrading dependencies that are years old?

Yes, once tests exist, because unsupported dependencies eventually force the issue at a time you do not choose — a security advisory, a platform deprecation, a certificate that will not renew. With a safety net it becomes bounded work rather than an act of faith.

Can this be done without disrupting the business?

The stabilisation portion is largely invisible to users, because it changes how the system is managed rather than how it behaves. That is one of its advantages over a replacement, which is disruptive by definition.

What does it cost?

Quoted per phase after an initial assessment. The urgent portion is small and we would generally do it first and separately, because it is a poor use of everyone's time to negotiate a full scope while backups remain unverified.

Other situations

Recognise this?

Tell us what it looks like in your business. We will tell you what we would do about it, and whether it is worth doing.

Get in touch

Tell us what you are trying to change

Describe the problem rather than the service — the two frequently differ, and working out which is which is the useful part of a first conversation. We reply within one working day, and if it is outside what we do well you will hear that in the reply rather than after a call.

We use what you send to reply to you. Nothing else, and no list.

WhatsApp