High contribution cost drives teams around the system
Aliases: shadow UI · contribution cost · bypass
What it is
Getting a change into the shared library runs a gauntlet: proposal, review, accessibility, token alignment, docs, a release window. Each step is defensible; stacked, they can outlast the product team’s own “good enough in our repo” calendar. When the transaction cost of contributing stays above the cost of the side path, teams ship outside the system. Those shipments rarely flow back. That is contribution friction producing bypass: not an unguarded door, a door whose transit time turns would-be contributors into a crew working off-site.
What they leave behind is shadow UI — widgets that look like system pieces and obey none of the theme, version, or defect contracts.
Why it happens
Contribution is a transaction. A product line compares “wait for the shared merge” with “finish it on the feature branch and ship with the story”. The latter has a date; the former often does not. Uncertainty has a price: a sprint cannot depend on “a button that might land next week”. So private buttons and private dialogs grow on the feature branch. They never enter the docs site, never consume semantic aliases, never ride a version bump; the next rebrand or contrast fix will not reach them. Higher friction, denser shadow UI. Adoption numbers can still look healthy because the old main path still calls the old pieces, while new paths have already set up shop next door.
Friction comes from serial waits, repeated proof, and unpredictable refusal — not from “someone is allowed to say no”. A gate can be fast. A gate plus four weeks of silence is expensive.
Where it stops holding
Regulated work (payments, clinical, markets with accessibility lawsuit risk) must keep some checks as hard gates; there the cost is insurance, not runaway friction. The real test is whether required checks run in parallel, have a time bound, and return an actionable refusal. A one-maintainer library already has a short path; friction talk has no object. Hackathons and exploration branches may bypass if they expire or re-enter; exploration without an expiry is permanent shadow. When the product is frozen and no longer admits primitives, high cost is an intentional close — say “this window takes no new pieces” out loud, rather than impersonating an open door with a long process.
Applying it
- Time a typical contribution: calendar days from proposal to “product repo can import it”, round-trips, silent waiting days. Publish that number to consumers.
- Parallelize checks that can run together (contrast, keyboard, token references in one day). Give each stage a maximum wait. Silence past the limit counts as pass-and-log, not as infinite hang.
- Offer a side door: land in the product repo first, return within an agreed window, delete on failure to return — so temps do not quietly become ownerless canon.
- Check: in the last two iterations, list new buttons / dialogs / inputs in product repos that do not import the shared library. If most authors can point to “the front door would have missed our ship date”, friction is already minting shadow UI. Lay “front-door cycle” next to “feature ship cycle”: when the former is systematically longer, bypass is the default strategy, not a few people cheating.
Related
- Same group: R1.06.1 Who may add a component must be named · R1.06.2 An ungoverned system decays into a component pile · R1.06.4 Promote only after several real call sites exist · R1.06.5 Review the public API, not the implementation internals · R1.06.6 Maintenance is accepted with the component, not after the merge
- Adjacent: R1.18 Adoption and compliance metrics · R1.12 Usage guidelines and anti-examples
- Search terms:
contribution friction·shadow UI·bypass the system