The three models, and their real costs
Every treatment of this subject lands on the same three shapes. They are genuinely different and the choice matters, but the framing hides that all three answer only one of the three governance questions.
| How it works | What it costs | |
|---|---|---|
| Centralised | A dedicated team owns the system. Product teams consume it and request changes | The team becomes a bottleneck, and product teams route around it under deadline. Quality is high; adoption is the risk |
| Federated | Contributors across product teams own parts of the system, with shared standards | Coherence erodes. Nobody owns the whole, so the parts drift and no single person can see it happening |
| Hybrid | A small core team owns foundations and review; product teams contribute components | The most common answer and the hardest to hold. It works exactly as well as the boundary between core and contributed is defined |
Hybrid is usually right, and the reason it fails is not the model. It fails when nobody wrote down what belongs in the core, so every contribution becomes a negotiation and the core absorbs things it should not have.
The question the models do not answer
Contribution governance decides how the system changes. Compliance governance decides whether anyone follows it. The second is where systems die, and it is barely discussed because it is unglamorous.
The symptom is familiar: a well-maintained design system, an active contribution process, and a codebase with four hundred literal hex values in it. Nobody violated a rule deliberately. It was a Friday and the token did not quite fit and adding one hex was faster than a conversation, three hundred times.
Nobody violated the system deliberately. Adding one literal value was faster than a conversation, three hundred times.
There are exactly three enforcement mechanisms, and only one of them is free:
| Mechanism | Cost | Effectiveness | |
|---|---|---|---|
| Documentation | Write down what is correct | Free | Roughly as effective as free |
| Linting | Flag violations in the editor and fail them in CI | Real tooling investment, plus a rule set maintained alongside the system | High. Most of the return on governance effort is here |
| Removing the capability | Make the wrong thing impossible to express | Every genuine new need becomes a request to the system owners | Total, within the boundary it covers |
Both of the effective rows have published precedents worth studying. Salesforce's SLDS 2 ships a linter and a validator that scan markup against a rule database and recommend fixes — the middle row, at enterprise scale. Stripe's app UI toolkit takes the bottom row: its css prop accepts named tokens and nothing else, several components refuse overrides entirely, and component hierarchy constraints restrict what may contain what.
If you can only do one thing, add a single CI check that fails on a literal colour value outside your token file. It takes an afternoon and it stops the most common form of drift permanently. Everything else in governance is negotiable; this is not.
The bottom row is only available on surfaces you control. Stripe can remove the capability inside its own dashboard and cannot inside your checkout — which is why it ships a customisation ladder there instead. The posture follows the boundary, not the preference.
When a governance problem is a structural problem
The most useful governance lesson in public is one a team published about their own mistake, and it is not about rules at all.
Spotify's Encore launched with a deliberately flexible mobile subsystem. Product teams asked it for more and more specific components, and it kept saying yes. By 2022 the team judged that the pendulum had swung too far toward flexibility and that a recalibration was needed.
The obvious governance response would have been to tighten the process: stricter acceptance criteria, a higher bar for new components, more review. They did something else. They built a new layer between the flexible subsystem and the foundation, described as a first line of defence that reduces the demand on the specialised subsystem while increasing platform parity.
That reframes a governance problem as an architecture problem, and the reframe generalises. When one part of a system is drowning in requests, the requests are usually not specific to it — a shared layer is missing underneath. Refusing them pushes teams to build outside the system, where you lose sight of the work entirely. Adding the layer captures it.
| Looks like | Usually is | |
|---|---|---|
| Constant requests for new components | Contributors not respecting the process | A missing shared layer between the core and the specialised subsystem |
| Teams building outside the system | Poor adoption discipline | The system says no faster than it says yes |
| Component tokens multiplying | Sloppy contributions | The semantic layer is missing something everyone needs |
| Rules that keep needing exceptions | Rules being ignored | One rule covering two surfaces that legitimately differ |
The last row is worth a specific check. A rule with a caveat in it — "generous spacing, though tables may be denser" — is two rules pretending to be one. Every exception request against it is correct, and no amount of governance fixes that.
What changes when the contributor is a model
Governance frameworks assume a rhythm: a person proposes a change, a person reviews it, the cadence is bounded by human throughput. That assumption is no longer safe.
An agent writes forty screens between reviews. It has no memory of your conventions across sessions, no incentive to cut corners and no ability to ask a colleague which grey is right. Two things follow, and they pull in opposite directions.
| Effect | |
|---|---|
| Contribution process | Less load. Agents rarely propose changes to the system itself — they consume it |
| Compliance enforcement | Much more load. Volume of code written against the system rose; review capacity did not |
| Ambiguity in the system | Far more expensive. A human unsure which token to use asks; a model picks silently, in every file |
| Undocumented convention | Worthless. Anything held only in people's heads is now simply absent |
The last row is the sharpest change. Most design systems have always been part written and part folklore, and the folklore worked because a developer who had seen the previous ten screens absorbed it. That transmission mechanism does not exist for an agent, so every unwritten convention becomes a gap the model fills from its training data.
We sampled 299 DESIGN.md files written specifically to close that gap. 76% contain no prohibitions of any kind, 86% specify colours as raw hex with no semantic role, 69% define no dark mode and 44% state no concrete size value anywhere. Those are governance documents that govern nothing — and unlike a wiki nobody reads, this one is being read, on every single request.
Identity Forge design kits are the governed artefact in this sense: semantic colour roles across light and dark, type and spacing scales, motifs, and an explicit do's and don'ts list, serialised into a DESIGN.md that every agent reads before writing. Browse the kits, or read how to document a system for AI.
Minimum viable governance
Most published governance advice assumes a dedicated platform team, which most teams do not have. This is what the same job looks like without one.
- 1
Write down what belongs in the core
One paragraph. What may never be overridden — colour roles, type scale, spacing scale, prohibitions — and what is free to vary per surface. Most contribution arguments are actually arguments about this boundary, held without anyone naming it.
- 2
Add one CI check
Fail the build on a literal colour value outside the token file. This single check does more than a contribution process, and it costs an afternoon.
grep -rn --include='*.tsx' --include='*.css' -E '#[0-9a-fA-F]{3,8}\b' src \ | grep -v 'tokens\|globals.css' && exit 1 || exit 0 - 3
Name one owner, not a committee
Someone who can say yes in a day. A system that takes two weeks to approve a change is a system teams will route around, and routing around is unrecoverable — the work happens outside where you cannot see it.
- 4
Review by surface, not by component
Once a quarter, open three screens from the same surface side by side. Drift is invisible per-file and obvious in comparison, which is why per-pull-request review never catches it.
- 5
Track exception requests as system defects
Every request for an exception is evidence that a rule covers two cases that differ, or that the semantic layer is missing something. Handle the request, then fix the cause. A rule that needs three exceptions is a rule that was written wrong.
Step four is the one teams skip and the one that finds the most. Reviewing a pull request tells you whether that file is consistent with itself. Only comparing finished screens tells you whether the product is consistent with itself, and that is the thing the system exists to protect.
What is design system governance?
The rules covering who may change the system, how contributions are proposed and accepted, and how compliance is enforced. Most discussions cover the first two thoroughly and the third barely, which is unfortunate because the third is where systems usually fail.
What is the difference between centralised and federated governance?
Centralised means a dedicated team owns the system and product teams request changes — high quality, with a bottleneck risk. Federated means contributors across teams own parts under shared standards — better throughput, with coherence erosion as the risk. Hybrid splits them: a core team owns foundations and review, product teams contribute components.
How do I get teams to actually follow the design system?
Mechanically. A linter that flags violations in the editor and fails them in CI does more than any documentation, and removing the ability to deviate — a token-only styling API, for instance — is stronger still where you control the surface. Documentation alone has close to no enforcement value.
My design system team is overwhelmed with requests. Should we say no more often?
Check first whether a layer is missing. Spotify hit this with Encore and added a shared layer between the flexible subsystem and the foundation rather than tightening acceptance, because the requests were not actually specific to that subsystem. Refusing requests pushes teams to build outside the system, where the work becomes invisible.
Does governance change now that AI writes most of the UI?
The balance shifts sharply. Agents rarely propose changes to the system, so contribution load falls, while the volume of code written against it rises without review capacity rising — so enforcement load climbs. Ambiguity gets more expensive too: a person unsure which token to use asks, and a model picks silently in every file it touches.