Sure, you might have the specification that the original developer was given, but every developer brings their own opinions and hard-won experience to a project. Just because the specification says "outgoing messages are sent to a queue" and the program links with ZeroMQ, doesn't tell you whether that's a design goal or a temporary stop-gap proof-of-concept. Maybe the program is structured so it can use an email queue for distributed operation. Maybe the program is designed to be linked into a larger system and just push message structs onto an in-memory vector.
I think if a project was that important, the people who needed something patched would be able to get it together even if the original maintainer went missing.
The original analogy to the challenges of knowledge transfer isn't totally applicable. Knowledge transfer is important to organizations because figuring everything out all over again would be costly, not because it would be impossible.
You certainly care about what it will do tomorrow too (so you can keep up, or avoid having it break stuff for you), but if it goes unmaintained, you don't have to worry about that since it does the job for you.
OTOH, I've been on projects where a dependency was chosen on the promise of what they will do in the future. That future never materialized, so we were left with a bunch of unfinished dependency code, maintained a bunch of components ourselves etc — it was a mess, in short. So I never rely on promises, only on what's there today.
Whatever it was originally meant to do is probably either obsolete, or well known to all users, if it's been so long the original devs left.
If it's got ZeroMQ, and has for 5 years, one can probably assume someone will be upset if it suddenly does not have ZeroMQ.
Regardless of intent, for practical purposes, if people are using it, they probably want that to stay around until you do an orderly transition to some other thing.
Reverse-engineering all that can be an utter nightmare even with tests. I suggest that people who disagree consider, for example, the word "reverse-engineer" as in how they might reverse-engineer a car.
Usually you have this kind of problem when it's NOT producing desired results and the problem is how to make it do something that's needed without affecting some set of usecases that you don't understand yet.
gn
We solve problems with code, or by finding ways to avoid writing code.
We translate vague requirements into things a computer can handle, or we translate between computer languages, because any spec that was complete would just be the program. That's why they keep us. The computers can do pure logic on their own.
Opinion is very much a part of it because pure logic is just a useless pile of text unless it has something to do with the real world, which is full of opinions.
Even inside the program itself, we aren't dealing with logic. Languages are designed for human minds, and compilers are meant to catch mistakes people make. Libraries are often chosen for all kinds of perfectly good nontechnical reasons, like "That one is actually maintained" or "Everyone already knows this" or "People seem to like this" or "That seems like it won't be a thing in 3 years".
If your whole entire source code is so innovative that you can't immediately understand it, there might be trouble, but so much code is or can be pretty boring.
At most, changing something will make a bug that's not really in the spec but is something everyone wants and relies on, but isn't immediately obvious, then you'll have to fix it.
The trouble is that if knowledge is lost, people will probably not bother to figure it out, and starting fresh might be more appealing.
The bigger issue especially in open source is that if there's no activity, there might not be any in the future. It could be abandoned for 10 years and perfectly fine, until a change is needed, and even if the change is easy and the knowledge is there, it might not happen if nobody cares anymore, and you'll have to fork it yourself, so maybe you choose the actively maintained thing even if it's less complete or more complex or ugly to use.