logoalt Hacker News

Use the Mikado Method to do safe changes in a complex codebase

131 pointsby foenixlast Thursday at 3:03 PM65 commentsview on HN

Comments

bob1029today at 6:43 PM

My favorite tool for trying scary complicated things in an unknown space is the feature flag. This works even if you have zero tests and no documentation. The only thing you need is the live production system and a way to toggle the flag at runtime.

If you can ship your hypothesis along with an effectively unaltered version of prod, the ability to test things without breaking other things becomes much more feasible. I've never been in a real business scenario where I wasn't able to negotiate a brief experimental window during live business hours for at least one client.

show 4 replies
charles_ftoday at 3:26 PM

Write tests. Most likely those 300k lines of code contain a TESST folder with 4 unit tests written by an intern who retired to become a bonsai farmer in the 1990s, and none of them pass anymore. Things become much less stressful if you have something basic telling you you're still good.

show 3 replies
nitnelavetoday at 8:09 PM

Also known as "Make the change easy, then make the change"

Something to realize is that every codebase is legacy. My best new feature implementations are always several commits that do no-op refactorings, with no changes to tests even with good coverage (or adding tests before the refactoring for better coverage), then one short and sweet commit with just the behavior change.

show 2 replies
Illniyartoday at 5:01 PM

This is a good method if you are stuck and you don't know what you need to do. It also helps explore a project with a specific task in mind.

It is not very useful in giving you confidence your changes would not cause unexpected side effects, which is usually the main problem working with legacy code.

If you want confidence when working with legacy code, your best bet is to do a strangler fig pattern - find a boundaries for the module you want to work on, rewrite the module (or clone and make your changes), run both at the same time in shadow mode, monitor and verify your new module is working the same as the old one, then switch and eventually delete the old module.

show 1 reply
yomismoaquitoday at 4:25 PM

I recommend reading a classic, "Working Effectively With Legacy Code" from Michael Feathers.

nuancebydefaulttoday at 9:03 PM

I've been a few times in a situation where I needed to make significant changes in a huge codebase with lot's of tests but also with a lot of corner cases, on my own.

I've spent blood sweat, tears and restless evenings scrolling and ctrl-f-ing huge build and test logs to finally accomplish the task.

But let's take a step back.

So they assign you to get that done. You're supposed to be careful, courageous and precise while making those changes without regression. There's very little up-to-date documentation on the design, architecture, let alone any rationale on design choices. You're supposed to come up with methods like Mikado, tdd, shadowing or anything that gets the job done.

Is this even fair to ask? Suppose you ask a contractor to re-factor a house with old style plumbing and electricity. Will they do it Mikado style, or, would they say - look - we're going to tear things down and rebuild it from the ground. You need to be willing to pay for a designer, an architect, new materials and a set of specialized contractors.

So why do we as sw engineers put up with the assignment? Are we rewarded so much more than the project manager of that house who subcontracts the work to many people to tear down and rebuild?

show 1 reply
mittermayrtoday at 3:57 PM

While great in theory, I think it almost always fails on "non-existent" testing structures that reliably cover the areas you're modifying. I change something, and if there's no immediate build or compile error, this (depending on the system) usually does not mean you're safe. A lot of issues happen on the interfaces (data in/out of the system) and certain advanced states and context. I wouldn't know how Mikado helps here.

In other words, I'd reword this to using the Mikado method to understand large codebases, or get a first glimpse of how things are connected and wired up. But to say it allows for _safe_ changes is stretching it a bit much.

show 2 replies
csourstoday at 7:57 PM

This sounds like torture (as written).

Of course, working in a legacy codebase is also torture.

Software development is a hyper-rational endeavor, so we don't often talk about feelings. This article also does not talk much about feelings.

Reading between the lines, it looks like reverting the code is supposed to affect how you feel about the work. Knowing that failure is an explicit option can help to set an expectation; however, without a mature understanding of failure, that expectation may just be misery.

With a mature understanding of failure, the possibility of a forced rollback should help you "let go" of those changes. It's like starting a day of painting or drawing with one that you force yourself to throw away; or a writing session with a silly page.

----

If someone thinks that they are giving you good advice, but it sounds terrible, then maybe they are expecting you to do some more work to realize the value of that advice.

If you are giving someone advice and they push back, maybe you are implying some extra work or expectations that you have not actually said out loud.

Advice is plagued by the tacit knowledge problem.

show 1 reply
jeremyscanvictoday at 6:12 PM

Is it possible in practice to control the side effects of making changes in a huge legacy code base?

Maybe the software crashes when you write 42 in some field and you're able to tell it's due to a missing division-by-zero check deep down in the code base. Your gut tells you you should add the check but who knows if something relies on this bug somehow, plus you've never heard of anyone having issues with values other than 42.

At this point you decide to hard code the behavior you want for the value 42 specifically. It's nasty and it only makes the code base more complex, but at least you're not breaking anything.

Anyone has experience of this mindset of embracing the mess?

show 3 replies
woodruffwtoday at 8:44 PM

I was hoping it was a reference to The Mikado, given that the best way to refactor is with a short, sharp shock[1].

[1]: https://en.wikipedia.org/wiki/Short,_sharp_shock

brutuscattoday at 5:48 PM

For me now days is like this: - try to locate the relevant files - now build a prompt, explain the use case or the refactor purpose. Explain the relevant files and mention them and describe the interaction and how you understand that work together. Also explain how you think it needs to be refactored. Give the model the instruction to analyze the code and propose different solution for a complete refactor. Tell it to not implement it, just plan.

Then you’ll get several paths of action.

Chose one and tell the model to write into a file you’ll keep around while the implantation is on going so you won’t pollute the context and can start over each chunk of work in a clean prompt. Name the file refactor-<name >-plan.md tell it to write the plan step by step and dump a todo list having into account dependencies for tracking progress.

Review the plans, make fixes if needed. You need to have some sort of table reassembling a todo so it can track and make progress along.

Open a new prompt tell it analyze the plan file, to go to the todo list section and proceed with the next task. Verify it done, and update the plan.

Repeat until done.

aggetoday at 3:39 PM

Using a Mikado style graph for planning any large work in general has been really useful to me. Used it a lot at both Telia back in 2019 and Mentimeter at 2022.

It gives a great way to visualise the work needed to achieve a goal, without ever mentioning time.

spprashanttoday at 8:37 PM

I d like to hear more about people who have jumped onto large codebases and were instantly productive. I see a lot of emphasis on documentation and comments, but in my experience they get stale real fast.

Mikhail_Ktoday at 5:16 PM

I usually use the method "shout Banzai! and charge straight like a kamikaze"

Is that the Mikado method?

eblumetoday at 2:50 PM

I’ve been using a form of the Mikado Method based on a specific ordering of git commits (by message prefix) along with some pre commit hook scripts, governed by a document: https://docs.eblu.me/how-to/agent-change-process

I have this configured to feed in to an agent for large changes. It’s been working pretty well, still not perfect though… the tricky part is that it is very tempting (and maybe even sometimes correct) to not fully reset between mikado “iterations”, but then you wind up with a messy state transfer. The advantage so far has been that it’s easy to make progress while ditching a session context “poisoned” by some failure.

w10-1today at 7:22 PM

Ah, no: incremental approaches only work in already well-formed code.

Poor code requires not coding but analysis and decisions, partitioning code and clients. So:

1. Stop writing code

2. Buy or write tools to analyze the code (modularity) and use-case (clients)

3. Make 3+ rough plans:

(a) leave it alone and manage quality;

(b) identify severable parts to fix and how (same clients);

(3) incrementally migrate (important) clients to something new

The key lesson is that incremental improvements are sinking money (and worse, time) into something that might need to go, without any real context for whether it's worth it.

aggetoday at 3:51 PM

There is a great interview that talks about the process and what it is about more generally: https://youtu.be/HbjWOvxJjms?si=5ta-JOyfFLub2yX_

I think there are similar methods, such as nested todo-lists. But DAGs are exceptionally good for this use case of visualising work (Mikado graphs are DAGs).

dirkctoday at 5:50 PM

The things that always get me with tasks like this is that there are *always* clear, existing errors in the legacy code. And you know if you fix those, all hell will break loose!

theo1996today at 3:10 PM

1. take a well known method for problem solving basically any programmer/human knows 2. slap a cool word from the land of the rising sun 3.??? 4. profit! This article is painfully pretentious and stealth marketing for a book

show 1 reply
hidelooktropictoday at 3:28 PM

So you do things one step at a time and timebox as you go? This method probably doesn't need its own name. In fact I think that's just what timeboxing is.

show 2 replies
dvhtoday at 3:01 PM

Inherited? I wrote the thing! Customer have no money for large refactoring.

show 1 reply
janpottoday at 2:44 PM

In 2026, we call this "plan mode"

show 1 reply
koakuma-chantoday at 3:08 PM

> The project doesn’t compile anymore.

Using a programming language that has a compiler, lucky.

frpdrptoday at 9:28 PM

[dead]