MaboaSoft Engineering Team

The Bus Factor Is Zero: Recovering Product Knowledge from a Legacy Repository

When the people who understood a legacy system are gone, the repository becomes the last surviving specification. Before refactoring or rewriting, teams need to recover the product model: roles, flows, integrations, constraints, risks, evidence, confidence, and unknowns.

The Bus Factor Is Zero: Recovering Product Knowledge from a Legacy Repository

The bus factor was three, until it became zero.

One engineer changed jobs. One contractor disappeared into another project. One person who “knew how billing really works” is still in the company, but now leads a different department and only answers Slack on Fridays.

The system is still running. Customers still depend on it. Finance still closes the month through it. Support still has workarounds that never made it into Jira.

And the only complete specification left is the repository.

That is where legacy modernization stops being a refactoring problem and becomes a knowledge recovery problem.

Legacy Repository Discovery is the discipline for that recovery: treating the repository as evidence, reconstructing the product model, and separating verified behavior from folklore before anyone starts rewriting code.

TL;DR — When the people who understood a legacy system are gone, the repository is the last surviving spec. Before rewriting, recover the product model — roles, flows, integrations, constraints, risks — as evidence-backed claims with explicit confidence and unknowns. Skipping this is not modernization; it is a bet that the missing knowledge did not matter.

The bus factor is not funny once it hits zero

Bus factor is an old software joke with a useful edge: how many people have to disappear from a project before the team loses critical knowledge?

If the number is three, the team has some resilience. If the number is one, one person has become part of the architecture. If the number is zero, the knowledge has already gone and the system is now being operated by archaeology, habit, and production incidents.

This is common in legacy software. The original team built a product under real deadlines. They encoded business rules in controllers, SQL queries, mobile screens, background jobs, permission checks, import scripts, email templates, and one conditional that nobody wants to touch. Some of it was documented. Some of it was discussed in meetings. Some of it was obvious at the time.

Then the company changed. The team changed. The market changed. The code stayed.

The dangerous moment is when a company decides to modernize before it understands what it is modernizing. A rewrite starts. A migration plan appears. An AI assistant is pointed at the repository. A backlog is created from partial memory.

That is the gap behind our AI engineering and Code-to-Spec work: before a team can lock behavior with tests or re-platform safely, it has to recover what the current system actually does.

That is not modernization. That is a bet that the missing knowledge was not important.

The repository becomes the last surviving specification

When the team no longer remembers the system, the repository is not just code. It is evidence.

Not perfect evidence. Not complete evidence. Not always current evidence. But evidence.

Useful product knowledge can be scattered across:

  • routes and screens;
  • permission checks and role guards;
  • database schemas and migrations;
  • seed data and fixtures;
  • tests and test names;
  • UI copy and translations;
  • import and export scripts;
  • scheduled jobs;
  • email and notification templates;
  • environment variables and deployment files;
  • SDK imports, hostnames, and provider-specific configuration;
  • README files, internal docs, comments, and old setup notes.

The mistake is treating one of those surfaces as truth.

A README can reveal vocabulary, but it may describe a deployment path that nobody uses anymore. A database table can reveal a product concept, but not every table is a business entity. A dependency can point to an integration, but not every package proves runtime behavior. A comment can explain intent, but comments are cheap to abandon.

Repository discovery works because it cross-checks surfaces. Product knowledge becomes stronger when UI, tests, configuration, data, and code all point in the same direction. It becomes weaker when only one stale document says it is true.

Do not start by documenting code

The first instinct is often to generate code documentation: class descriptions, endpoint lists, module summaries, diagrams of services and tables.

That may help later. It is the wrong first move.

The business question is not “which files exist?” The business question is “what product does this system implement?”

A Product Manager does not need a walkthrough of every controller before they can understand the product. A Business Analyst does not need a class list before they can write useful requirements. A CTO planning a migration does not need an exhaustive UML diagram before they can identify the risk.

They need to know:

  • who uses the system;
  • what those users can do;
  • which business capabilities exist;
  • how important flows move from start to finish;
  • which external systems are involved;
  • which constraints shape behavior;
  • which decisions are visible in the repository;
  • which risks are supported by evidence;
  • which questions are still unanswered.

Implementation details matter when they explain one of those things. They should not become the subject by default.

Folder structure is not the product model. Framework choice is not the product model. A controller group is not automatically a feature. A database table is not automatically a business concept.

The repository is the source material. The output should be product knowledge.

Recover the Product Model first

Before writing final documentation, recover the working Product Model.

A Product Model is the answer to a basic question: if this repository is the evidence, what product does it imply?

That model should cover eight areas.

Roles. Who appears to use the system? Look for permissions, navigation, route guards, admin screens, seed users, tests, onboarding copy, and user-facing labels. Recover roles, not personas. A repository can often prove that an admin, operator, customer, approver, or external system exists. It usually cannot prove demographic personas.

Business entities. Which product concepts matter to users or operations? These may appear in schemas, forms, exports, reports, translations, fixtures, and UI tables. Avoid promoting every technical model into the glossary.

Capabilities. What can the product help someone accomplish? A capability may span screens, APIs, background jobs, and integrations. Name capabilities from the product point of view, not from the module name.

Flows. How does work move through the system? A flow is an ordered journey toward a business goal. It can be reconstructed from routes, forms, tests, state transitions, notifications, emails, jobs, and import/export paths.

Boundaries and integrations. Which external systems, providers, platforms, and operational handoffs matter? Separate confirmed runtime integrations from configured boundaries and dependency-only signals.

Constraints. What rules shape product behavior? Validation, feature flags, platform limits, scheduling rules, permissions, localization gaps, and deployment assumptions can all be product constraints.

Observable decisions. What decisions are visible from the repository? Record what can be observed. Do not invent the motivation.

Risks and unknowns. Which risks are supported by evidence? Which questions remain unresolved? A useful unknown is better than a confident guess.

This model should exist before the final knowledge base is written. Otherwise the output usually mirrors the repository structure instead of explaining the product.

Evidence, confidence, and unknowns

Legacy discovery fails when it turns weak evidence into confident prose.

Important claims need evidence. Not a pile of filenames, but a short explanation of what the repository proves.

For example:

Evidence:

- `web/src/routes.js` defines admin routes for participants, providers, settings, questions, and exports.
- `backend/server/src/main/resources/data/testusers.json` seeds provider and admin-style users.
  Confidence: Medium

That is more useful than:

The system has an admin portal.

The first version can be checked. The second version may be true, but it hides the boundary of the evidence.

Confidence is part of the claim. If multiple independent surfaces agree, confidence rises. If the claim comes from one stale doc, an ambiguous dependency, or static analysis without running the product, confidence should drop.

Unknowns are not a failure of the process. Unknowns are one of the main outputs.

A recovered risk entry might look like this:

Risk: Payment retry behavior is not confirmed
Impact: A migration could change billing recovery and customer notification timing.
Evidence:

- `billing/retry_job.*` schedules retry attempts after failed payment events.
- `emails/payment_failed.*` contains customer-facing failure copy.
- No test was found that confirms retry count, timing, or cancellation behavior.
  Confidence: Medium
  Next evidence: Run the billing flow in a staging environment or confirm behavior with production logs.

An unknown says:

  • what question remains open;
  • why it matters;
  • what evidence was checked;
  • what evidence would resolve it;
  • which roles, flows, features, or integrations are affected.

That is how a future stakeholder interview, runtime test, or production observation becomes targeted instead of vague.

What the knowledge base should contain

The end product should not be an encyclopedia of the codebase. It should be a connected knowledge base organized around product concepts.

A useful structure usually includes:

  • an inventory of repository surfaces examined;
  • a glossary of business terms;
  • role pages;
  • feature or capability pages;
  • flow pages;
  • integration and boundary pages;
  • constraint pages;
  • observable decision pages;
  • evidence-backed risk pages;
  • unknown pages;
  • a final review artifact.

The inventory should come first, but it should stay observational. “This repository contains a mobile app, backend service, SQL migrations, and provider configuration files” is inventory. “The product uses Firebase for analytics” is a product conclusion and needs evidence.

Overview pages should come last. They summarize what has been recovered. They should not become the place where unsupported product claims hide.

This matters because a legacy knowledge base is often used by people who do not read source code every day: product leaders, business analysts, solution architects, QA leads, support managers, and executives approving migration risk. They need the system explained in business language, with enough evidence that engineers can verify the claims.

Where AI helps, and where it cannot be trusted alone

AI is useful in repository discovery when it is constrained by method.

It can read faster than a human. It can cluster repeated terms. It can summarize routes, screens, schemas, tests, and configuration. It can compare old documentation with implementation. It can help maintain a canonical list of roles, flows, integrations, constraints, risks, and unknowns.

That does not make it a product owner.

AI should not invent:

  • personas from weak role evidence;
  • motivations for architectural decisions;
  • runtime behavior from dependency names;
  • client context that is not in the repository;
  • business strategy from implementation artifacts;
  • certainty where the evidence is thin.

The method matters more than the model. A careful discovery process asks the assistant to preserve uncertainty, cite evidence, distinguish configured boundaries from runtime integrations, and downgrade confidence when the product was not executed.

The dangerous version of AI repository analysis is not obviously wrong. It is plausible. It produces clean prose, confident summaries, and a knowledge base that looks complete while smuggling in guesses.

That is exactly what legacy modernization cannot afford.

From recovery to modernization

Repository Discovery fits naturally into Code-to-Spec work.

First, recover the product knowledge. Understand the roles, flows, capabilities, integrations, constraints, risks, and unknowns.

Then lock the critical behavior with tests. Those tests become the safety net for migration. (This is the role of characterization tests, as described in Michael Feathers’ Working Effectively with Legacy Code: document what the system actually does before you change it.)

Only then re-platform. This incremental, test-guarded path mirrors the strangler fig pattern for legacy modernization — and it applies directly to mobile apps, not only backends.

Without discovery, test generation can preserve the wrong assumptions. Without tests, modernization depends on memory and manual comparison. Without both, a rewrite can ship a cleaner system that no longer does the business-critical things the old one quietly did.

This is also where AI-assisted engineering needs discipline. The same failure mode we describe in AI Technical Debt in Mobile Development applies here: fast output is not the same as verified understanding.

We publish a dated Repository Discovery skill snapshot on GitHub for teams that want to inspect the method. The public copy may lag behind current internal practice, but it shows the principle: recover the product model before changing the system.

If you are planning a legacy migration and the current system is better understood by production than by the team, start with discovery. MaboaSoft can help recover the product model, turn critical behavior into tests, and modernize without guessing. Book a 20-minute call.

FAQ

What does bus factor mean in software? Bus factor is the number of people who would need to leave a project before the team loses critical knowledge. A bus factor of zero means the knowledge has already left, while the system still needs to be operated, fixed, or modernized.

When should legacy repository discovery start? Start discovery before a rewrite, migration, AI-assisted refactor, major onboarding effort, or critical bug-fix program. If the team cannot explain the product behavior with evidence, discovery should happen before modernization planning.

Why not rewrite the legacy system first? A rewrite before discovery can preserve the wrong behavior, remove hidden business rules, or miss operational constraints. Repository discovery recovers the product model first so modernization can be tested against what the system actually does.

Can AI analyze a legacy repository safely? AI can accelerate reading, clustering, summarizing, and cross-checking repository evidence. It is not safe when it invents missing business rules, runtime behavior, client context, or decision rationale. Claims still need evidence and confidence.