Leverage AI
AI Strategy · Agentic Patterns

Hora's Watchmaker: Decompose, Interface, Map, Dumb Recompose

📖 This article has an expanded ebook edition — read the full ebook.

One pattern on five surfaces — because the worker dies every hour and the work has to survive it.

Scott Farrell · LeverageAI · July 2026

TL;DR

Everyone who builds with coding agents notices the same thing within a fortnight: smaller files work better. Break the thousand-line module into six and the agent stops mangling it. Split the book into a file per chapter and the writer stops losing the plot. Pull the prompt out of the Python and into its own markdown file and suddenly you can actually maintain it.

And everyone reaches for the same explanation. It fits the context window better.

That explanation is true, it is comfortable, and it is about a quarter of the reason. Worse, it comes with an implied expiry date — if the problem is window size, then bigger windows will solve it, so this is a workaround rather than an architecture. Two years of larger windows later, the practice has not gone away. It has become more valuable.

The real explanation is older than agents, older than transformers, and older than most of the people arguing about context length. It was published in 1962, in a paper about why complex systems in nature are almost always hierarchical.

Two watchmakers and a ringing phone

Herbert Simon's The Architecture of Complexity opens its section on evolution with a parable.1 Two watchmakers, Hora and Tempus, both make excellent watches of about a thousand parts each. Both are in demand, so the phones in their workshops ring constantly.

“Tempus had so constructed his that if he had one partly assembled and had to put it down — to answer the phone say — it immediately fell to pieces and had to be reassembled from the elements. The better the customers liked his watches, the more they phoned him, the more difficult it became for him to find enough uninterrupted time to finish a watch.”1

Hora built the same thousand-part watch from stable subassemblies of about ten parts each; ten of those made a larger subassembly; ten of those made the watch. When his phone rang he lost only the piece in his hand.

Simon does not leave it as a fable. He works the arithmetic. If the probability of interruption while adding any one part is one in a hundred, then Tempus takes, on average, about four thousand times as long to finish a watch as Hora.1 Hora makes 111 times as many complete assemblies, but he loses roughly a twentieth of the work per interruption and completes nine attempts in ten instead of forty-four per million. The conclusion is one sentence:

“Complex systems will evolve from simple systems much more rapidly if there are stable intermediate forms than if there are not.”1

Now ask what an LLM agent's working life actually looks like. Context windows fill and end. Sessions die. Compaction eats the middle of the history mid-task. The next agent that picks up the work starts cold, with no memory that the previous one existed.

Key Insight

An agent's normal condition is Hora's ringing phone — except the phone never stops ringing. A monolith forces every agent to be Tempus.

That is the whole argument, and it is why this is not borrowed software hygiene. Decomposition is how work outlives the worker, and your workers die every hour. Everything else in this piece is mechanism.

The component has more jobs than anyone counts

“Fits context better” is one job. There are at least four, and each one prevents a different, specific failure.

The component is the unit of…BecauseThe failure it prevents
AttentionIt fits the window with room to thinkThe load-bearing detail buried mid-context and never attended to
EditThe filename is the addressA patch landing in the wrong span — the classic “it deleted a chunk I didn't ask it to touch”
RegenerationIt is the largest thing you can cheaply delete and rebuild from its specHaving to regenerate a whole document to fix one section
ParallelismIndependent components have no shared write surfaceTen agents fanned out and a merge conflict for every one of them

The unit-of-edit row is the one people misremember. The early-model disasters — the ones where a coding agent would confidently delete forty lines you never mentioned — looked like comprehension failures. They were addressing failures. The model could not reliably locate a span in a thousand-line sea, so it approximated, and the approximation ate your code. Small files make the filename the address. A bigger window does not give you an address.

Which is the point that matters, and the reason this pattern did not expire:

Bottom Line

Only the attention constraint relaxed when windows grew. Addressing, regeneration and parallelism are properties of the system, not of the model — so they never relax. A thousand lines in a glass vial is still bad design.

Since the first version of this argument, the canon has added two more jobs. The component is also the unit of reuse — when regeneration is cheap the value order inverts, and the complete application becomes the most disposable layer while the compact invariant that generates it becomes the asset worth carrying.6 And it is the unit of reach: how far an agent can travel through meaningful relationships before it loses the intent is bounded by how big each hop is. Better models spend their extra reasoning budget on travelling further rather than thinking harder about a fixed packet — which means every improvement in agent quality revalues a well-cut corpus without a single page being rewritten.7

Six jobs. One decision. That is unusual leverage for a design choice most teams make by accident.

The four moves

The pattern is not “split things up”. It is four moves, and the fourth is the one nobody names.

1. Decompose — choose the unit by closure, not by size

The wrong question is “how many lines?”. The right one is: what is the smallest bundle whose meaning is complete without its neighbours? A heading without its body is not a component. A punchline without its setup is not a component. Two mutually reinforcing boxes split into lonely orphans are not two components; they are one component, badly cut.5

Size is an output of that judgment, never an input.

2. Interface — a cheap face on an expensive body

Every component needs a description that lets a caller decide whether to open it, and that costs far less than opening it. A function signature. A chapter card. A one-line index entry. A page's claim list.

This is Parnas's information hiding, from 1972, and his paper is more useful than its reputation. Parnas's actual argument is not “make modules” — it is that the criteria you use to draw the boundaries determine whether modularity helps at all:

“It is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart. We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.”2

Cut on the things likely to change, and hide each one. Cut on processing steps — the flowchart cut, the one that feels natural — and every interface carries a design decision, so every change crosses several modules at once.

The modern version of a cheap interface is generated rather than written. Aider's repo map parses source with tree-sitter, builds a reference graph, ranks symbols by PageRank and renders just signatures and structure, not full implementations, inside a token budget.3 That is a deterministically generated interface layer over an expensive body, and the agent decides when to descend past it.

3. Map — a manifest you can trust without reading the parts

index.md. The outline file. The table of contents. The call graph. The typed edges between wiki pages. The map's job is to be complete, current and deterministic — something you can regenerate mechanically, not something a model has to infer.

Get this wrong and the decomposition is worse than the monolith, because now the pieces exist and nobody can find them.

4. Dumb recompose — the leg nobody names

Here is the move that separates this pattern from generic modularity, and it is the one most teams skip.

Assembly must contain no intelligence. A function call. include 'chapter_3.php'. Concatenation in outline order. php index.php > index.html.4 If your components are joined by a model that reads all of them and works out how they fit, you have not removed the monolith. You have moved it to the seam, where it is harder to see and impossible to test.

Remember

Intelligence in the components. A cheap interface on each one. A mechanical map that glues the interfaces together. If composition requires judgment, you re-imported the monolith problem at assembly time.

There is a hard case, and it is worth stating because it is where the rule earns its keep. Sometimes the join genuinely is difficult — fusing the results of a dozen parallel investigations, say. The answer is not to make the recompositor clever. It is to put the judgment at the ends: a model frames the probes, deterministic code performs the union, the provenance, the route counts and the thresholds, and a model then reads the fused object and decides.8 AI judgment, then deterministic compilation, then AI judgment. The middle stays stupid on purpose.

One move, five surfaces

The reason this deserves the word pattern rather than practice is that the same cut runs on things that have nothing physically in common.

Code

Functions and classes, forever. Plus the AI-era addition: prompts extracted into their own markdown files, because a prompt buried in a function is a component with no address and no interface. And the boundary itself has moved — increasingly the human-owned source is the retained package of intent, design, prompts and tests above the generated code, with the code as compiled output.9

Artifacts

An outline file as the map. One markdown plan per chapter. One PHP file per rendered chapter. include as the recompositor. The writer holds one chapter's context at a time; the build is a shell command. This article's ebook edition is compiled exactly that way — it is its own worked example.

Agents

The mega-agent with fifty tools and a thousand-line prompt is a monolith wearing a costume; single-responsibility workers behind a thin router are components.10 And the cut has more than one axis: the scout–senior split divides one task along a time seam — gathering, then judging — passing the entire transcript across intact rather than summarising it.11 Same pattern, cut along time instead of topic.

Knowledge

Run the lens over a wiki-graph and the correspondences stop being metaphor. Pages are functions. Typed edges are the call graph. The index is the manifest. Claims are statements. And the janitor — the maintenance agent that merges redundant claims, converts prose to edges and splits bloated pages — is a refactoring engine. Merging claims is deduplication. Claim-to-edge is extract-method. Splitting a page is splitting a class. Lint is the test suite.

The question itself

The newest surface. A hard question is not one query; the parent intent is the invariant and individual searches are disposable probes serving it.8 Decompose the intent into probes, run them in parallel, fuse deterministically, judge once. Same four moves, applied to the job rather than to the artefact.

You did not build a knowledge base that resembles a codebase. You built a codebase whose language is claims — and imported forty years of software maintenance discipline for free. That is why the janitor works: refactoring is a solved craft.

Where to cut — the part that is actually hard

Simon's phrase was nearly decomposable, and the qualifier is load-bearing. In a nearly decomposable system the short-run behaviour of each component is approximately independent of the others, and long-run behaviour depends only in an aggregate way.1 Approximately. Some concerns cut across everything. That is why edges exist.

Which gives you the first diagnostic. A page, module or agent with edges to everything is the god-object smell: not a component that needs shrinking, but a signal that the cut lines are drawn in the wrong place and several real components are fused inside it.

Simon has a name for the healthy case too, and it is the most quotable line in the paper:

“Most things are only weakly connected with most other things; for a tolerable description of reality only a tiny fraction of all possible interactions needs to be taken into account.”1

If your graph does not look like that — sparse across, dense within — you have not found the joints.

Three tests for a proposed cut line

  1. The change test (Parnas). List the decisions most likely to change. Does each proposed boundary hide one? If a likely change crosses four components, the boundary is wrong.2
  2. The interface-cheaper-than-body test. Can a caller decide whether to open the component from its interface alone, at a small fraction of the cost of opening it? If not, you have made a filename, not a component.
  3. The family test. Give two independent agents only your description of the unit. If the things they produce share a nameable invariant and differ mainly in local fit, the cut names something real. If they share only a buzzword, you have a slogan.6

What it costs, and where it doesn't apply

Two honest notes, because a doctrine that only describes the happy path is marketing.

The burden moved; it did not vanish. Decomposition buys you addressability, cheap regeneration, parallelism and reach, and charges you interface maintenance, map maintenance, and the standing judgment of where the boundaries should sit. The trade is good because the costs are stewardship of an asset that compounds, while the thing you avoided — recalibrating a monolith after every change and every model release — is work that evaporates. But it is a trade, not a free lunch.

It does not always pay. If a piece of work will be produced once, never edited, never regenerated, never parallelised and never traversed again, decomposition is pure overhead. Decompose where the work will be revisited. That is the whole boundary, and it is why a throwaway script should stay a throwaway script.

And one thing this piece deliberately does not claim: there is no measured multiplier for decomposition in agentic systems. Simon's four thousand is a closed-form calculation about watch assembly at a stated interruption probability, not a measurement of anything an agent does. It tells you the shape of the penalty — superlinear in the size of the thing you are holding when the phone rings — and shape is enough to act on.

The hard part was never writing the modules

Sixty-four years after Simon, thirty-eight years of “keep it modular” later, the interesting part of this has not changed. Anyone can split a file. The judgment is in the cut — which decisions to hide, where meaning closes, what the interface has to carry, and how to keep the join stupid enough to trust.

What has changed is the penalty for getting it wrong. In 1962 a bad decomposition cost you rework. In 2026 it costs you an agent population that cannot address, cannot regenerate, cannot parallelise and cannot travel — a workshop full of Tempuses, all of them starting over every time the phone rings.

The ebook. This article is the summary. The full edition runs the argument to ground: the six jobs of a component with the failure each one prevents, the four moves as an artefact, the software-to-knowledge correspondence table, the five planes worked end to end, and the cut criteria as a usable checklist — plus the boundary conditions and the experiment that would settle the open question.

A companion piece, File Back the Walk, picks up exactly where this one stops: decomposition creates the stable units, and that book covers what traversing them leaves behind.

References

  1. Simon, Herbert A. “The Architecture of Complexity.” Proceedings of the American Philosophical Society, Vol. 106, No. 6 (1962), pp. 467–482. — “Tempus had so constructed his that if he had one partly assembled and had to put it down… it immediately fell to pieces”; “it will take Tempus, on the average, about four thousand times as long to assemble a watch as Hora”; “complex systems will evolve from simple systems much more rapidly if there are stable intermediate forms”; “most things are only weakly connected with most other things.” https://www2.econ.iastate.edu/tesfatsi/ArchitectureOfComplexity.HSimon1962.pdf
  2. Parnas, D. L. “On the Criteria To Be Used in Decomposing Systems into Modules.” Communications of the ACM, Vol. 15, No. 12 (December 1972), pp. 1053–1058. — “It is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart. We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change.” https://wstomv.win.tue.nl/edu/2ip30/references/criteria_for_modularization.pdf
  3. Aider. “Repository Map.” — tree-sitter parsing into a reference graph, PageRank ranking, rendering signatures and structure rather than full implementations, within an adaptive token budget. https://aider.chat/docs/repomap.html
  4. PHP Manual. “include.” — the mechanical recompositor used to build the ebook edition of this article. https://www.php.net/manual/en/function.include.php
  5. Farrell, Scott. “Semantic Decompilation.” LeverageAI. — claims as functions, typed edges as calls, and the over-atomisation warning: pure atomisation destroys meaning. https://leverageai.com.au/wp-content/media/articles/article.php?article=153-semantic-decompilation
  6. Farrell, Scott. “Generative Design Patterns.” LeverageAI. — the family test, and the inverted reuse hierarchy in which the complete application becomes the most disposable layer. https://leverageai.com.au/wp-content/media/articles/article.php?article=147-generative-design-patterns
  7. Farrell, Scott. “The Wiki Playbook.” LeverageAI. — the Traversal Dividend and usable graph radius: how far an agent travels before losing the intent. https://leverageai.com.au/wp-content/media/articles/article.php?article=176-the-wiki-playbook
  8. Farrell, Scott. “The Intent Compiler.” LeverageAI. — the parent intent as the invariant unit of work; AI judgment, deterministic compilation, AI judgment. https://leverageai.com.au/wp-content/media/articles/article.php?article=141-intent-compiler
  9. Farrell, Scott. “The Prompt Is Source.” LeverageAI. — the retained human-owned package above generated code as the real source. https://leverageai.com.au/wp-content/media/articles/article.php?article=154-the-prompt-is-source
  10. Farrell, Scott. “Micro-Agents, Macro-Impact.” LeverageAI. — the monolithic agent trap, and the router / supervisor / worker decomposition. https://leverageai.com.au/wp-content/media/articles/article.php?article=16-micro-agents-macro-impact
  11. Farrell, Scott. “The Scout and the Senior.” LeverageAI. — splitting one task along a time seam and passing the whole transcript across it intact. https://leverageai.com.au/wp-content/media/articles/article.php?article=71-the-scout-and-the-senior