The Ledger, Both Columns
What it bought, in the order the value actually shows up:
- A fix has one home. The original argument, and still the smallest one. A defect in the shared layer is repaired once and deployed, rather than repaired once and forgotten twice.
- A divergence has a home too. The larger one. The cross-app bug in the first track lived in a gap that belonged to nobody. An owner means the gap has an address, and things with addresses get tests.
- Convergence surfaces decisions. Unifying three implementations forces somebody to answer questions each author had been answering by default — error posture, vocabulary, what happens when something is missing.
- An app converging on the shared layer improves it. Three of four conversions changed the shared component, each with a fix its authors had never needed.
- The next sibling is cheap. A new app consumes the plumbing from birth instead of growing its own copy of it.
And what it costs, stated as plainly:
- A deploy step in every shared change, and a window during which the system is in a state nobody designed for.
- A rule people can forget, which is why the drift check is not optional.
- A constant pull toward becoming a framework, resisted only by a rule stated at birth and checked deliberately.
- Coordination on shared files. A change to the shared layer is a change to every consumer, and that is true whether or not anybody wanted it to be.
The Honest Test for Whether You Need One
Most codebases with duplication should not build this. The test is not "do we have duplicated code" — everyone does. It is closer to three questions, and the third is the one that decides:
- Is the duplicated layer identical by design? If the copies differ because the apps genuinely differ, extraction produces a parameter-riddled function serving nobody.
- Has a divergence already cost you something? Not "could it" — has it. A cross-app defect, an inconsistency somebody reported, a fix applied in two places out of three.
- Would every consumer accept a shared answer to the questions the copies are currently answering separately? If not, you do not have a plumbing problem; you have several apps that need to disagree, and the honest structure is separate implementations with a written contract between them.
The Sentence to Leave With
Everything in this quest reduces to one move, applied over and over: give the thing an owner, and make the correct outcome the default.
The plumbing got an owner. The gap between two vocabularies got an owner. The panel's likeness got an owner. And each time the enforcement that actually held was not a rule somebody had to remember, but a default that made passing nothing correct, a check that failed a test suite, or a value generated in one place and delivered everywhere.
Rules that live in documents lose to context. Rules that live in defaults and failing tests do not — which is the same lesson the workshop that produced this quest was built on, arrived at from the opposite direction.