How Do You Hand a Codebase to Someone Who Was Not There?
A codebase handover is not a meeting or a walkthrough video. It is four artefacts: a setup that runs, the decisions behind the code, access that is genuinely granted, and a map of where things live.
On This Page

A developer leaves on a Friday. On Monday, somebody who has never opened the repository is asked to change something inside it. The code is byte-for-byte identical to what it was on Thursday. The team’s ability to change it is not.
Closing that gap is the entire job of a codebase handover, and most attempts close the wrong half of it. The usual ritual is a two-hour screen share, a recording nobody watches twice, and a README updated by the one person who did not need it. That transfers narrative. It does not transfer capability.
Our position: a handover is an artefact problem, not a meeting problem. Four artefacts do nearly all of the work. A setup that runs on a machine that has never seen the project. The decisions behind the code, written down while somebody still remembers them. Access that has actually been granted rather than promised. And a map of where things live. The same discipline applies at the opposite end of an engagement, which is why what a technical discovery should produce reads like this list written backwards.
What a codebase handover actually loses
Nobody loses the code. It is in version control and it compiles. What walks out of the door is the layer around the code: why the retry limit is three, which of the two payment modules is live, which failing test is flaky rather than broken, and the fact that the staging database has been pointing at a production credential since a hotfix last spring.
Teams call that layer tribal knowledge, which is a flattering name for a documentation failure with a long fuse. It works perfectly right up until the person holding it takes a fortnight off.
Some of what disappears can be recovered by reading carefully. Most of it cannot. Four categories account for nearly all of the pain:
- Constraints invisible in the code. A vendor rate limit, a client compliance rule, a legacy integration that must keep receiving a field nobody reads any more.
- Rejected alternatives. The two approaches tried before this one, and what went wrong with each. Without them, the next engineer confidently reimplements the second-best option.
- Operational habits. Which alert is real, which deploy window is safe, what to do when the queue backs up on a Sunday evening.
- Ownership. Who to ask about billing, who controls DNS, who has to sign off before a schema changes.
None of that is exotic. All of it is expensive to rediscover, and rediscovery always happens at the worst possible moment, because a bad moment is what sends someone looking in the first place.
Artefact one: a setup that runs
Start here, because it is the only artefact you can objectively test. Take a laptop that has never seen the project. Follow the written instructions exactly as written, changing nothing, inferring nothing. If the application is not running locally at the end of it, the handover has not begun.
The clone-to-running clock
We time this. Not to hit a target, but because a clock exposes what prose hides. Every point where the newcomer has to ask a question is a defect in the document, and the defects cluster in the same four places: an undocumented runtime version, a private package registry, an environment variable with no example value, and a migration that assumes a database somebody has to create by hand first.
The fix is dull and it works. One command that installs, one command that runs, and one file listing every environment variable with a safe placeholder and a single line explaining what it is for. If the setup genuinely needs eleven steps, write eleven steps, and mark which ones can fail harmlessly. A pipeline definition helps here in a way a wiki page cannot: because a build workflow is executed rather than read, it cannot quietly go stale. Anything the pipeline does is documentation with a test attached.
Seed data is part of the setup
An application that starts against an empty database is not running, it is idling. Nobody can tell a working checkout from a broken one without an order in it. Ship a seed script that creates a realistic set of records: a user, an item, a completed transaction, and one deliberately awkward record with an apostrophe in the name and a missing optional field.
This is also where quiet security debt surfaces. If the only way to get useful local data is to restore a copy of the production database onto a laptop, you do not have a seeding problem, you have a data handling problem, and a handover is a good moment to say so out loud rather than inherit it silently.
The person who wrote the setup cannot verify it. They will autocomplete the missing steps from memory without noticing they did. Hand the document to a colleague from a different project, watch them run it, and write down every question they ask. Those questions are the missing lines, in order.
Artefact two: the decisions, not the diagram
Architecture diagrams age badly and lie confidently. A diagram drawn eighteen months ago describes an intention; the code describes reality, and the two drift apart without anybody deciding they should. Decision records age well, because a decision stays true about the moment it was made whether or not the system still reflects it.
What a record actually holds
Five lines. It does not need to be longer, and longer ones do not get written.
- The decision itself, in one sentence, in the present tense.
- The date, and who was in the room when it was taken.
- The constraint that forced it: cost, a deadline, a contract, a skill the team had or lacked.
- What else was considered, and the specific reason each option lost.
- What would make this decision wrong later. This is the line teams skip and the one that pays for the exercise.
"We chose a single database because write volume is low; revisit when the ingestion job starts competing with user traffic" tells the next engineer exactly what to watch. It converts a decision into a trigger, which is the only form of documentation that ages in the reader’s favour. The most consequential version of that trigger is usually storage, which is why we set it out separately in choosing a database you will not regret.
When to write one
Not for everything. A record per pull request is a filing system nobody opens. Write one when a choice is expensive to reverse, when two reasonable engineers disagreed, or when the answer will look wrong to somebody who was not there. That last trigger catches most of what matters, and it happens to be the definition of a handover risk.
Keep the records in the repository, beside the code, under the same version control as everything else. Git history already answers when and who; a record answers why, and the two together are close to a complete account. It is also why our approach captures the decision log during delivery rather than after it, when the reasons have already softened into opinions. And a team that chose deliberately conservative tools simply has less to explain, which is an underrated argument in boring technology, deliberately: the handover document is shorter because the stranger has met most of it before.
Artefact three: access that has actually been granted
This artefact fails most often and gets the least attention, because it is administrative rather than technical. Code is transferable by nature. Access is not. It sits in individual accounts, personal tokens, a registrar login inside somebody’s password manager, and a two-factor prompt going to a phone that has left the building.
Write the inventory before the notice period, not during it. Every row below has a verification step, and a row without one is a rumour.
| Access class | Where it usually hides | What breaks without it | How to verify |
|---|---|---|---|
| Source control | A personal account holding the only admin rights | Nobody can grant the next person access | A second owner exists and has signed in |
| Deployment pipeline | A token issued to one engineer | Builds fail quietly once the account closes | Rotate the token, then watch a deploy pass |
| DNS and domains | A registrar account bought on a personal card | Certificates lapse and mail stops arriving | Two reachable contacts on the account |
| Production data | A shared credential nobody rotates | Restores cannot be tested at all | Run a restore into a scratch environment |
| Third-party services | Sign-in tied to one founder’s address | Billing lapses before anyone notices | The billing contact is a role, not a person |
| Secrets and keys | Values typed by hand into a dashboard | The environment cannot be rebuilt | Recreate it from the documented list alone |
The fourth row deserves a moment. A restore you have never run is a hypothesis, and it usually fails for an access reason rather than a data reason: the snapshot exists, and the only account that can read it belongs to somebody who left in March. That is the argument of is your backup a backup, or just a copy in the same place, applied to people instead of storage.
Every account, token, domain and billing relationship has at least two humans who can administer it, and both have signed in recently enough to know the password still works. An account with a single owner is an outage with a date on it, and the date is chosen by someone else.
Artefact four: the map of where things live
A new engineer’s first question is never "how does this work". It is "where do I look". The map answers that, and it is the cheapest document in the set, because it is mostly a list of directories with one honest sentence each.
Honest is the operative word. "utils: shared helpers" is not a map entry, it is a shrug. "utils: date formatting and currency display only, and anything else in here is a mess we have not cleaned up" is a map entry, because it tells the reader where to look and where not to put things.
The map should also name what is not visible in the folder tree: which service owns the source of truth for a customer record, which two directories look alike and which of them is dead, where scheduled jobs are defined, and which areas nobody should change without a review. Inheriting an unfamiliar system and improving it are the same skill, which is why the first weeks of product improvement work look almost identical to a handover.
Add one more list while you are in there: what the system depends on that you do not control. Runtimes, libraries, vendor APIs, a certificate with a renewal date attached to a calendar nobody shares. Automated dependency checking makes the library half visible on every build, which turns a periodic panic into a routine one.
One trick worth borrowing on the content side. If editorial copy lives as files in the repository, the map covers the words as well as the code. A structured content workspace such as Acrosite generates those files, commits them to GitHub and triggers the configured deployment, so the content history and the code history are one history. A handover then needs no separate chapter titled "how do we change the words on the pricing page".
Write the documentation for a stranger
Here is the rule that improves all four artefacts at once, and the one teams resist hardest: assume the reader was never here. Not a new hire with an onboarding buddy and a friendly channel. A stranger, months from now, at eleven at night, with an incident open and nobody available to ask.
Documentation written for a colleague is thick with implied context. It says "the usual deploy process", "the client’s staging box", "ask the person who built the invoice job". Every one of those is a dead link the moment the team changes shape. Documentation written for a stranger names the process, gives the hostname, says what the invoice job does and where its schedule is defined.
The stranger test
Take any page of internal documentation and cross out every proper noun that refers to a person. Then read what is left. If it no longer tells you how to do the thing, that page was a memory aid rather than a document. Rewrite the crossed-out parts as roles, systems and file paths, and the page starts working for people who have never met the author.
There is a genuine cost here and it should be stated plainly. Writing for a stranger takes longer, and some of what you write will never be read by anyone. We think the trade is clearly worth making, but it is a cost rather than a free win, and pretending otherwise is exactly how documentation initiatives die in week three.
It also changes what the documentation is for. A handover packet is, in the end, an honest description of what the work actually was, which our parent company approaches from the commercial side in what a company actually sells.
A sequence that works when somebody is leaving
Handovers fail on ordering as much as on content. The common mistake is opening with a code walkthrough, which is the least durable thing in the room and the easiest to nod along to. Run it in this order instead.
- Inventory the access first. Before any technical conversation. It is the only item with a hard external dependency, and the only one that becomes harder after the last day rather than easier.
- Have the leaver do a clean setup. On a borrowed machine, from the written instructions. They will find four undocumented steps inside twenty minutes, because they know precisely where to look.
- Write records for the last year of decisions. Not the whole history. Ask one question on repeat: what did we do here that would look wrong to somebody who was not in the room?
- Draw the map, then let someone else redraw it. The leaver writes version one. The person taking over rewrites it after a week. The differences between the two versions are the real gaps.
- Run an incident rehearsal. Break something in staging and let the new owner fix it while the leaver watches and says nothing unless asked. This step tests capability rather than comprehension, and it is the one people skip.
- Do a supervised release. The new owner ships to production, the leaver observes. After that the leaver does not ship again, even on the days when it would obviously be faster.
Step five is worth defending, because it is the one that gets cut for time. Comprehension is easy to fake during a walkthrough. A broken staging environment at four in the afternoon is not.
A handover is finished when the person who left could be unreachable for a month and nobody would need to try.
Where we would start, and when this advice reverses
If you have a week, spend all of it on access and the setup. Those two have hard failure modes: without them nothing else can even be attempted. Decision records and the map degrade gracefully, because a partial map still helps. A missing registrar login helps nobody.
If you have a month, add the decision records and the incident rehearsal, and run the setup test twice with two different people. The second run finds everything the first person happened to already know, which is usually more than they realised they knew.
The advice reverses in one case, and that case is more common than it sounds. If the codebase is genuinely going to be replaced within the year, do not document the code. Document the behaviour instead: what it does, for whom, with which inputs and outputs, and which of those behaviours are contractual rather than accidental. A rewrite needs a specification, not an explanation of code that is about to be deleted. Confusing the two is how a replacement turns into an archaeology project.
And if nobody is leaving, run the handover anyway, once a year, against a colleague who does not work on the system. It is the cheapest audit available and it takes about a day. It is also the difference between ongoing maintenance that behaves like a service and maintenance that behaves like a rescue. If you have inherited something and cannot yet tell which of the two you are holding, describe what you have and we will tell you what is missing from it.
Common questions.
What should be included in a codebase handover?
Four artefacts cover most of it. A setup document that takes a fresh machine to a running application without anyone asking a question. Decision records explaining why the code looks the way it does. A complete access inventory covering source control, deployment, DNS, data and third-party billing. And a map naming each part of the repository, including the parts that are dead. Video walkthroughs are optional; these are not.
How long should a handover take?
Plan for weeks rather than days, and start with access rather than code. Access transfer has external dependencies, such as registrars and vendors, that cannot be rushed once someone has left. A single afternoon can produce a usable setup document and map for a small system. Decision records and a supervised release take longer because they need the departing engineer available while the new owner works.
What is a decision record?
A decision record is a short document capturing one technical choice, stored in the repository alongside the code. It states the decision in a sentence, the date and the people involved, the constraint that forced it, the alternatives that were rejected and why, and the conditions under which the decision should be revisited. It differs from a diagram because it stays accurate even after the system it describes has changed.
How do you document a codebase that was never documented?
Work backwards from the tasks people actually perform rather than forwards from the folder structure. Document how to run it locally, how to deploy it, how to restore it, and how to handle the three failures that occur most often. Then add a directory map with one honest sentence per folder. This produces something usable in days, whereas attempting to describe every module usually produces nothing at all.
What access should be transferred before a developer leaves?
Everything that only they can administer. Source control ownership, deployment tokens, DNS and registrar logins, database and backup credentials, secrets stored in hosting dashboards, and any third-party service where sign-in or billing is tied to their personal address. Verify each one by having a second person use it, not by ticking a list. An account with a single owner will eventually cause an outage.
Should you document a legacy system you plan to replace?
Document its behaviour, not its implementation. Record what the system does, who depends on each output, which inputs it accepts, and which behaviours are contractual rather than accidental. That becomes the specification the replacement is measured against. Writing detailed explanations of code you intend to delete wastes the time of the people writing it and misleads the people reading it later.
Facing this in your
own business?
Tell us where you’re headed — we’ll map the shortest honest route.