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

Before opening the editor, week one is spent reading what the system actually did yesterday
Inheriting 200K lines of spaghetti code has an order, and it starts nowhere near your editor. Days one and two you measure what the system actually did yesterday: which routes real traffic hit, which jobs ran, which tables anyone wrote to. Day three you try to boot the whole thing on a clean machine and put a stopwatch on it. Day four you read the commit history instead of hunting for documentation. Day five you count how many tests assert anything at all. The last two days you write two lists: what you can already promise, and what you are forbidden to touch.
That second list is the one that matters. No refactoring, no swapping libraries, no "while I'm in here anyway". The only change allowed in week one is the kind that makes the system observable: logs, metrics, alerts. You still have no idea what breaks, and spaghetti code breaks in places that have no visible relationship to the file you opened.
The question "I've inherited 200K lines of spaghetti code, what now?" has been sitting on Stack Exchange since 2012 with a score of 463, 19 answers and north of 200,000 views. Those answers are decent advice for the engineer about to open the editor. They are useless to the person who has to answer the board on Friday. What follows is the order we use on rescue engagements, written for whoever owns the budget conversation.

Clean-machine setup time is the cheapest health check you will ever run
Code tells you what somebody intended to build. Logs tell you what the business actually runs on. The gap between the two is usually grotesque, and it decides where your next quarter goes.
Four measurements fit in two days and require zero understanding of the codebase:
On one of these reads I found an endpoint being hit 11,000 times a day by a customer whose contract had ended months earlier. Their integration kept calling, our server kept answering, nobody noticed. Turning it off cut roughly 30% of the database bill without touching a single business rule.
This is surveying the structure before you drill into a wall. You do not find the load-bearing column by reading the original drawings, because the drawings changed three times during construction and nobody redrew them.
Take a laptop with nothing installed and try to run the system from scratch using only what the repository tells you. Time it, and write down everything that was missing: the environment variable nobody mentioned, the runtime version that only exists on the departed developer's machine, the database dump someone parked in a personal Drive folder.
That number is the cheapest health indicator you will ever get. Forty minutes and three Slack messages means the system is alive. Two days and a dependency on one specific human means you did not inherit a system, you inherited a person. And what you just wrote down is the first honest document the project has ever had, authored by someone who felt the pain.
The exit path deserves the same treatment. I once inherited a 50-minute deploy and called it the best news in the audit, because a slow deploy is plumbing, with a known fix and an estimable timeline. A deploy nobody can reproduce is a different animal.

The forbidden-to-touch list is worth more than any refactoring plan on day seven
Docs lie because updating them is optional. Commits do not, because committing is how the code gets in.
The first command I run lists the most-changed files over the last twelve months. The top twenty are the real system: that is where the business changes, where the rules live, where you will spend the year. If a 4,000-line file called `utils` shows up at the top, you already know the rotten patch, and you already know why every small change turns into a week.
Then I look at authorship. When 70% of the last year's commits come from one person and that person left, the risk is not in the code, it is in the calendar. When they come from eight different vendors in eighteen months, the pattern is different: each one solved their slice the way they knew how, and now three distinct ways of hitting the database coexist in one repo. Our audit of 31 broken codebases showed the same numbers repeating, and none of them appear in a static analysis report.
Test coverage is the easiest number in the industry to fake. I have opened a repository with 92% coverage where a good share of the test files contained not a single assertion. The test called the function, the function did not blow up, the line was marked covered. That is quality theatre: the metric exists, the guarantee does not.
Its twin is monitoring without instrumentation, the famous `/health` that returns 200 because it was written to return 200. The dashboard stays green while the database is down.
On day five you fix none of this. You count. How many test files exist, how many assert, how long the suite takes, how many tests are skipped. That inventory is what later tells you whether review can be partly automated. Tooling handles the obvious, and I have written about how far you can take the human out of code review, but no tool knows which business rule that 2019 `if` statement was protecting.
The forbidden list is the most valuable artifact of the week, and it is what saves month two. Three lines, each with a written reason:
What you can do in those two days is the opposite of refactoring: instrument. Structured logs on the five busiest routes, error capture switched on, an alert on the nightly job that fails silently. Additive change, not destructive. Next month it is the difference between diagnosing in an afternoon and guessing for a week.
Fair objection, usually from someone who has already paid three vendors.
That week ships four things nobody in the company had: a map of what the system actually uses, the clean-machine setup time, the list of files where the business lives, and an honest test inventory. With those in hand, the Friday answer stops being a guess and becomes three separate timelines: how long to stop the visible bleeding, how long to find its source, how long to treat the disease. Days, then weeks, then months of medicine. Anyone quoting a single number is hiding the other two.
There is a side effect that matters to whoever signs the contract: a team that spends week one measuring is a team that will not ask for a rewrite in month three. The rewrite request is the standard move of people who never understood the system and need to hide that behind a new project. Some of what makes it so hard to understand never lived in the code at all, which is why we started measuring cognitive debt separately.
It does not apply to a system that is on fire right now. If checkout is down and the company bleeds revenue by the hour, you invert everything: stop the bleeding first, measure later, and accept that you will work blind for a few days. It also fits badly on a small codebase, say 8,000 or 10,000 lines, where reading all of it takes less time than building the instruments.
Outside those two cases I know of no shortcut. The question to take back to your own company is shorter than this article: if the person with the most commits in your repo resigned this morning, how many days would it take you to find out what they knew?
8 read minutes
Article content: