Founder of Revin. Engineer by training, specialist in software development and digital products.

Inheriting an undocumented system starts with understanding what already runs in production
You just got the keys to a system nobody documented. For the first two weeks, ship no features and refactor nothing. Do three things, in this order: boot the system from scratch on a clean machine while writing down every missing step, instrument what is already in production so you can see real errors, latency and volume, and draw the five or six paths that money travels through. The rest of the code is allowed to stay ugly until day 15.
The order matters more than the list. Stopping the bleeding is fast. Finding where the blood comes from takes longer. Treating the disease is a months-long course of medicine. Invert that and you announce a rewrite on day 4, disappear for a quarter, and come back having lost half the business rules along the way.
The question "I've inherited 200K lines of spaghetti code, what now?" has been sitting on Stack Exchange since 2012, past 200,000 views, 463 votes, 19 answers. Almost every answer argues about code quality. The first two weeks come before that argument: you still don't know what the system does, and no good decision comes out of not knowing.

The first real document of the project is the list of what was missing to boot it
Take a clean laptop, or an empty container, and try to run it. Write down everything that was missing: the env var that only lived on the machine of the dev who left, the database dump someone sends over Slack, the runtime version pinned to something from three years ago, the third-party service with no sandbox that nobody can test locally.
That scratch file is the first honest document the project has. In construction there's a thing called an as-built drawing: the plan of what was actually erected, not the one that came out of the office. That's what you're producing.
If it took you two and a half days, fine. The number that matters is the time between a new dev getting access and seeing the first request run locally. It becomes your progress metric for the next few months, and it's the one indicator the whole company understands without a translation layer.
Deploy goes in the same bucket. A 50-minute deploy anyone can trigger is better news than a 6-minute deploy only Dave knows how to run, and I've written about why that slow pipeline was the best thing in the audit. Slow, you optimise. Bus-factor-of-one, you pray.
The rotten-facade example that shows up in nearly every rescue: the system has a /health endpoint, it answers 200, there's a colourful panel somewhere, and none of it measures anything that actually breaks. The metric exists. The guarantee doesn't.
Install the basics and stop: structured logs with a request id, error grouping in any capture tool you like, response time per route at the edge. None of that touches business rules, so the risk is low and week one is enough.
One week of real production data teaches you more about the system than a month of reading code. You find out three routes carry almost all the traffic. That a good chunk of the slowness, close to half in the codebases that came through here, sits in half a dozen chained queries inside a loop. And that the error that "happens sometimes" happens around 400 times a day with nobody watching. We pulled the same pattern out of 31 broken codebases.

Technical debt only makes the board agenda when it becomes a business sentence
Legacy software has no map, but it has people who know where it hurts. Book an hour with support, an hour with finance, an hour with the longest-serving person in operations. Ask what customers call about, what jams at month-end close, and which spreadsheet exists today to work around the software.
You want to leave those calls with one page listing the flows that, if they stop right now, cost money today:
Five paths, each with an owner and log evidence behind it, are worth more than 200,000 lines mapped into diagrams. That list is also your priority ruler for the rest of the year.
That sentence will cross your mind on day 4. I almost never approve a full rewrite, and the reason is practical: the ugly code is the only living documentation of the business rules. The weird if in the middle of the order service is usually a contract signed with a large customer in 2019, and nobody on the current team knows it. A rewrite throws away the answer along with the question. Worth checking, too, who actually owns the code before anyone plans to replace it.
Where the advice breaks, and it does break: a runtime with no security support, a critical dependency unpatched for years, a stack you can no longer hire for. Then the maths flips, and even so you go piece by piece with the old system running beside you as the reference. I also don't know that a two-week plan makes sense for a 3,000-line app with forty users. One afternoon covers that.
Ask for the coverage number and distrust it immediately. A test with no assertion runs, passes, counts as a covered line and guarantees nothing at all. Green suite, calm deploy, customer on the phone.
Run mutation testing on one critical module. If nearly every mutant survives, you have quality theatre, and now you have proof of it to show. Same logic applies to the backup nobody ever restored, which is why we keep a quarterly validation protocol.
Don't try to write the whole suite in two weeks. Write characterisation tests on the five revenue paths, pinning current behaviour exactly as it is today, wrong parts included. It's a safety net, and it isn't quality yet. Quality comes later, once you know what you can touch without dropping revenue.
Don't bring a refactoring roadmap. Bring four artefacts: the README that boots the system from scratch, the panel with real production errors and latency, the revenue-path map with owners, and a short risk list with a date and a dollar figure next to each item.
Technical debt only reaches the board agenda when it's phrased as a business fact. "The billing job has no reprocessing, so one overnight failure delays a full day of invoicing" makes the CFO put the phone down. "We need to refactor the orders module" makes the CFO pick it up.
And if someone in the back of the room suggests replacing the whole team, price the rehiring and re-onboarding first, senior rates included, before the knowledge clock resets to zero. When the agency that built the system walked away and nobody left knows the code, that's where an embedded senior squad comes in, which is the rescue work we do.
Open the repository right now and answer one question: how long does a new dev take to boot this from scratch without asking anyone anything? If you don't know the number, day 1 is today, and the two weeks start counting.
7 read minutes
Article content: