Skip to content

Architecture recovery

Nobody reads a 500-file repository top to bottom and holds the whole structure in their head. Past a certain size, “what are the components, really?” stops being a reading task and becomes a clustering problem: given the entities and the dependency edges between them (see Components and dependencies), which entities belong grouped together, and which grouping is actually useful?

The diagram below shows that clustering step on a (plausible, invented) set of browser source files: an unstructured scatter on the left, the same files grouped into three recovered components on the right.

Twelve browser source files scattered with no visible structure, clustered by a recovery algorithm into three components: Networking, DOM & Layout, JS Engine

Before recovery After recovery

net_socket dom_node js_parser css_style http_cache dom_event js_gc tls layout cookie bytecode render_tree clustering Networking DOM & Layout JS Engine

Simplified — illustrative, not a complete architecture. The file names are invented but plausible; this is not an actual map of any browser’s source tree.

The core intuition every recovery approach shares: things that change together, or depend on each other heavily, belong together. If two classes are always edited in the same commit, or one calls the other constantly while barely touching anything else, they’re doing one job — even if they live in different folders. Recovery algorithms turn that intuition into an actual grouping, and different algorithms use different signals to decide what “belongs together” means:

  • pkg — follow the folders. Uses the existing package/directory structure as the component boundary. It’s the baseline every other result gets compared against, and the closest thing to “no algorithm at all.”
  • wca — merge the most similar. Starts with every entity as its own group and repeatedly merges the two most similar groups, based on how much they depend on each other, until a target number of components is reached.
  • acdc — look for known structural patterns. Scans the dependency graph for recognizable shapes — a hub with many dependents, a chain, a shared utility everything imports — instead of measuring pairwise similarity.
  • arc and limbo — group by what code is about. Instead of only looking at who-calls-whom, these cluster by the underlying concern or topic entities seem to share, so two files that don’t directly depend on each other but clearly serve the same purpose can still end up grouped.

None of these is “the correct answer” that the others approximate. They encode different definitions of what a component is, and on a real codebase they disagree — one might merge two folders that pkg kept separate, or split one directory that wca treated as a single lump. That disagreement is information, not noise: if every algorithm draws the same boundary around a group of files, that boundary is solid. If they scatter, the actual boundary is genuinely fuzzy — worth a second look, not a bug in the tool.

In arcade-agent: recover runs any of these five algorithms (pkg, wca, acdc, arc, limbo) against a parsed dependency graph and returns the resulting components — see Agent tools. The clustering approach itself descends from published architecture-recovery research; see Research for where each algorithm comes from.