It is three weeks after the goodbye lunch. The staff engineer who had owned half your platform for six years is gone, the Slack handle greyed out, the laptop returned. And now there is a change that has to happen. Marketing’s base image needs bumping for a CVE, or the old auth module is finally being pulled, or a shared Terraform module everyone forked from needs a breaking edit. Routine work. The kind they would have scoped in an afternoon without opening more than two tabs.

You open the repo. The code is all there. It is readable. Nothing is encrypted, obfuscated, or missing, and you can follow every function in it. And you still cannot answer the one question that has to come before you touch anything. If I change this, what else breaks.

The part that took me a while to see clearly is that this sounds like a paradox and is not one. You did not lose their understanding of the code. The code stayed. Git kept all of it. What left was something that was never in the repo to begin with: the map of how the repos depend on each other. Which services build on that base image. Which repos still import the auth module, at which version. Which of the forty Terraform consumers will actually break on the edit and which only look like they might. They held that map in their head, assembled over six years of being the person who got paged, and it walked out the door with them.

We have a number that is supposed to warn us about exactly this. It is called the bus factor, and on paper their leaving should have tripped it. The uncomfortable thing is that for most teams, the bus factor was quietly measuring something other than the thing that just hurt them.

The bus factor you were measuring was an authorship number

I want to be fair to the bus factor, because the concept is good and the people who formalised it did careful work. The informal definition is clean: the minimum number of people who have to disappear before a project stalls. A bus factor of one is the canonical danger. And there is a real research literature behind making it computable, going back to the truck-factor work on version-control history and continuing into recent papers that model a project as a bipartite graph of contributors and the files or tasks they own. The commercial calculators do the same thing in a friendlier wrapper. Point them at a repository, read the commit history, and see which files only one person has meaningfully touched.

Notice the input in every one of those. It is the commit log. Bus factor, as it is actually computed, is a function of authorship. Who wrote this file, who has touched it since, how concentrated that history is. That is a genuine signal, and it answers a genuine question. If this person leaves, which code has no second author.

But “which code has no second author” is not the question you are stuck on three weeks after the departure. You are not missing the authorship of the auth module. You can read it. You are missing what depends on it across the other eighty repos, and that fact was never written into any commit. Authorship concentration and dependency knowledge are two different quantities, and the standard bus factor only measures the first. The senior could have pair-programmed every line they ever wrote and pushed the authorship bus factor to a comfortable three, and you would still be sitting here unable to bump the base image, because the thing that broke was never about who typed the code.

So it is worth naming the quantity the standard bus factor misses, because it is the one that actually decides how bad a departure turns out to be.

A dependency bus factor is the number of people who have to leave before your organisation loses the ability to answer “what depends on this” across its repos. It is not about who wrote any given service. It is about who can still tell you, once they are gone, which repos consume a shared module, at which version, and in what order those repos break when it changes. Where the classic bus factor is computed from commit authorship inside repos, the dependency bus factor lives in the edges between them: the Dockerfile FROM lines, the go.mod requires, the Helm value references, the Terraform source blocks, the GitLab CI includes. A team can have a perfectly healthy authorship bus factor and a dependency bus factor of one, and the second number stays invisible right up until the one person who held the cross-repo map in their head hands in their notice.

What actually walked out the door

There is a whole genre of good writing about inheriting an unfamiliar codebase, and I do not want to wave it away, because the advice in it is sound. Start from the edges. Find an entry point and trace it. Run the thing under a debugger and watch what executes. Make small, safe refactors as you go to anchor what you have learned. Talk to whoever is still around. If your problem is “I have been handed one large application and I do not understand its internal logic,” that advice will get you there.

The problem three weeks after a senior leaves is a different shape, and reading harder does not solve it. The auth module is two hundred lines and I understood it the first afternoon. What I cannot get by reading it is the set of repos elsewhere in the org that require it, because that information is not in the module. It is distributed across every other repo’s manifests, and no single repo I open will reveal it. The base image is worse, because the dependency runs through indirection the file does not spell out. A leaf service builds FROM acme/runtime-base, which is itself built FROM debian, so the repo I am editing does not even mention the thing I am actually trying to reason about. The senior knew the base was two hops up. The Dockerfile does not say so.

This is why the dependency bus factor is its own quantity and not just “bus factor for teams that documented badly.” The knowledge is not absent because someone was lazy about comments. It is absent from any one place by construction, because a cross-repo dependency is a fact about the relationship between two repos, and a relationship does not live inside either endpoint. The senior was, in effect, a human index over those relationships. The index is what you lost, and an index is exactly the thing reading one repo at a time cannot rebuild.

Why the handover doc was never going to hold it

The standard answer to all of this is the knowledge transfer plan. Get it out of their head before they go. Shadowing, a handover document, a wiki page, a fortnight of overlap if the timing is kind. And for a lot of what a senior carries, that genuinely works. The “why did we ever do it this way,” the war stories, the half-broken vendor integration nobody should touch on a Friday afternoon. Tacit, judgement-shaped knowledge, the kind you can only get by asking. Write it down. It is worth every hour.

But the people who run knowledge transfer for a living are blunt about where it fails. It runs on memory and goodwill, and both are unreliable narrators. The person leaving leaves out half of what they carry, not from carelessness but because the deepest knowledge is the most internalised, the kind they have stopped noticing they have. And the dependency map is the worst possible candidate for hand-capture, for a reason that has nothing to do with effort. It is large, it is mechanical, and it goes stale on the next merge. The afternoon someone writes “services X, Y and Z build on this base,” a fourth team adds itself, and the page is now wrong and nobody knows it is wrong. This is the same failure that makes platform teams quietly abandon their service catalogues. A hand-maintained map of what depends on what is only ever as accurate as the last person who remembered to update it, and “remember to update it” is precisely the discipline that does not survive the one person who cared about it leaving.

So the handover captures the things only a human can give you and quietly drops the one thing you most needed to keep, because that thing is too big and too volatile to write down by hand. You come out of it with the stories and without the map.

The one piece of what they knew that you never had to transfer

Here is the move, and it is almost annoying once you see it. The dependency map is the single part of what the senior knew that you did not need them to transfer at all. Because unlike the war stories and the judgement calls, it is not tacit. It is written down already, just not in prose. It is in the manifests. Every FROM line, every require, every chart reference, every module source is a dependency edge the senior had memorised and the repo had already declared. You do not have to get it out of anyone’s head. You can read it straight off the files, deterministically, the same answer every time you ask. Parsed, not inferred.

That is the real split between the two kinds of knowledge a departure takes. The semantic stuff, the intent and the patterns and the reasons, is genuinely lost when the person goes, and a handover is your one shot at it. The structural stuff, the graph of what depends on what, was never really theirs to take. It only felt lost because the only working copy was the one in their head, and nobody had built the other one. I made the longer version of this argument when Meta published their tribal-knowledge writeup: the structural layer is the durable one precisely because parsers are deterministic and re-run on every push, while the human-written layer decays and needs constant tending. A senior leaving is that same argument arriving through a more painful door. You do not transfer the map. You parse it. The closest sibling to this piece, most of what a departing senior knew was in the repos all along, works the same split from the angle of the resignation itself.

Even if nobody is leaving

You do not have to wait for a resignation for this to bite, and the proactive version is where the number earns its name. If you want to lower your dependency bus factor on purpose, the first problem is that you cannot lower a number you cannot see, and you cannot see it from the commit log. The repos that should worry you are not the ones with the messiest history. They are the ones where a single person is the only owner and a lot of other repos depend on what that repo produces. The danger is the product of two things. Sole ownership, which the commit history can show you. And cross-repo fan-in, which it cannot. A repo one person owns that nothing else depends on is fine. A repo one person owns that forty other repos build on is a dependency bus factor of one with a blast radius attached, and it looks identical to the safe one if all you are reading is authorship.

That product, sole ownership crossed with how hard the rest of the org leans on the thing, is the actual risk surface, and you can only compute it if you have the dependency graph to multiply the ownership against. Find those repos while the person who owns them is still in the building, and a future departure becomes a routine offboarding instead of a three-week archaeology dig.

Two bus factors

So, stripped down. There are two numbers here, and the departure showed you which one you had been watching.

The authorship bus factor is real and worth tracking. It is computed from your commit history, it tells you which code has no second author, and it is the one every existing tool measures. Keep an eye on it.

The dependency bus factor is the one that decided how bad last month actually was. It is not in the commit history. It lives in the edges between your repos, the same FROM lines and requires and chart references your manifests already declare, and it can only be computed from those. It was the part of what the senior knew that you could have kept without asking them to write a single word down, and the reason it felt catastrophic to lose is that nobody had built the copy that does not live inside a person.

When the senior left, the code stayed and the map walked out with them. The code was never the part you could not replace. The map was. And the map was the one thing you never needed a goodbye lunch to hand over, because it was sitting in your repositories the whole time, waiting to be read.

This is the query Riftmap exists to answer. Point it at your GitHub or GitLab organisation with one read-only token and it parses the cross-repo edges across every repo. Terraform, Docker, Helm, Kubernetes, GitHub Actions, GitLab CI, Ansible, Go modules, npm. “What depends on this module, at which version, owned by whom” becomes one query instead of one person. And because it crosses ownership against cross-repo fan-in, it will surface the single-maintainer, high-blast-radius repos, your dependency bus factor of one, while the person who owns them is still on the team. The graph is the copy of the map that does not resign.


Appendix: the argument in short

Claim. The bus factor every tool measures is computed from commit authorship, so it answers “which code has no second author.” The thing that actually breaks when a senior engineer leaves is different: the cross-repo dependency map they held in their head, which is in no commit and inside no single repo. Call that the dependency bus factor. It is the one part of what they knew that you can keep without a handover, because it is already declared in your manifests and can be parsed deterministically.

Dependency bus factor. The number of people who must leave before your organisation can no longer answer “what depends on this” across its repos. Computed from the dependency edges between repos (Dockerfile FROM lines, go.mod requires, Helm value references, Terraform source blocks, CI includes), not from commit authorship inside them.

FAQ.

  • Does the bus factor measure dependency knowledge? No. As computed in practice it measures authorship concentration from commit history. It tells you which code has a single author, not which repos across the org depend on that code.
  • How do you find what depends on what after the engineer who knew leaves? Not by reading the code, because the edges live between repos and not inside any one of them, and not reliably from a handover doc, because that goes stale on the next merge. You parse the dependency edges your manifests already declare and query the resulting graph.
  • Can a knowledge transfer plan capture cross-repo dependencies? Only by hand, and only as a snapshot. A hand-written “what depends on what” map is wrong the next time anyone adds a consumer, the same way service catalogues go stale.

Related reading.