---
title: 'Governance Model'
source: 'https://academia.sh/en/courses/design-systems/governance-model'
course: 'Design Systems'
language: en
updated: '2026-08-19T05:19:54+00:00'
license: 'CC BY-SA 4.0'
---

# Governance Model

Modeling centralized, federated, and hybrid governance over demand and capacity, queue time turning into local copies, the tipping point that shifts with scale, and separating decisions that must stay centralized.

The previous lesson's state machine did not ask one thing: who does the review?
Having all three approvals come from a single central team produces a different system
than having approvals come from within the contributing teams themselves.

The governance model is the answer to this question, and it is a choice between two
quantities: **consistency** and **speed**. If a single team reviews everything,
decisions are consistent but the queue grows; if every team reviews itself, the queue
shortens but decisions scatter. This lesson measures the trade-off with a model and
shows that the choice depends on scale.

## Three Models

**Centralized governance.** The system has a single owning team. Component design,
review, and release all pass through this team. Product teams propose contributions,
but the decision is central. Capacity is bounded by this team's size and does not grow
as the organization grows.

**Federated governance.** The system's components are distributed among the product
teams. Each team reviews and releases the components it owns internally. Capacity
grows together with team count. But the reviewer only sees their own product; they do
not know how the same decision was made in another product.

**Hybrid governance.** A core team holds the token layer, the naming convention, and
breaking-change approval; drafting and the first review happen inside the product
teams. Capacity depends on both the product teams' preparation capacity and the core's
approval capacity — whichever is smaller sets the bound.

What separates these three models is how much of the contributions are reviewed with
**an eye that sees the whole system**. The model below takes this ratio directly as a
variable and computes the deviation count from it.

## Building the Model

The model tracks three things: demand arriving per period, the model's capacity, and
the work accumulating in the queue. When the queue exceeds a certain duration, a
contribution is abandoned and that team writes its own copy; this copy is a deviation.
The second source of deviation is reviews carried out without system-wide visibility.

```js
// governance.mjs — comparing three governance models by queue time and deviation count

// Assumptions (all taken as this organization's measured values):
const PERIOD = 12;                  // how many periods to track
const DEMAND_PER_TEAM = 5;          // contribution demand a product team produces per period
const WAIT_THRESHOLD = 2;           // work waiting longer than this many periods is abandoned
const BASE_DEVIATION_RATE = 0.35;   // probability that a contribution reviewed without system-wide visibility deviates

// Models. "capacity" gives the number of contributions completable in one period;
// "visibility" gives how much of the contributions are reviewed with an eye that
// sees the whole system.
const MODELS = [
  {
    name: "centralized",
    capacity: () => 22,               // single team; independent of team count
    visibility: 0.95,
  },
  {
    name: "federated",
    capacity: (team) => 6 * team,     // each product team runs its own review
    visibility: 0.15,                 // spot-check review only
  },
  {
    name: "hybrid",
    capacity: (team) => Math.min(55, 6 * team), // product team prepares, core approves
    visibility: 0.70,
  },
];

function run(capacity, visibility, demand) {
  let queue = 0, accepted = 0, localCopy = 0, queueTotal = 0;
  for (let d = 0; d < PERIOD; d++) {
    queue += demand;
    const processed = Math.min(queue, capacity);
    queue -= processed;
    accepted += processed;
    const ceiling = WAIT_THRESHOLD * capacity;
    if (queue > ceiling) {
      localCopy += queue - ceiling;
      queue = ceiling;
    }
    queueTotal += queue;
  }
  const avgQueue = queueTotal / PERIOD;
  return {
    accepted,
    localCopy,
    wait: avgQueue / capacity,
    reviewDeviation: accepted * BASE_DEVIATION_RATE * (1 - visibility),
    finalQueue: queue,
  };
}

for (const team of [4, 12]) {
  const demand = DEMAND_PER_TEAM * team;
  console.log(`\n=== ${team} product teams · ${demand} contributions demanded per period · ${PERIOD} periods · total demand ${demand * PERIOD} ===`);
  console.log("model         capacity   accepted     pending    wait(periods)   review deviation   local copy   total deviation");
  const rows = [];
  for (const m of MODELS) {
    const cap = m.capacity(team);
    const s = run(cap, m.visibility, demand);
    const total = s.reviewDeviation + s.localCopy;
    rows.push({ name: m.name, total });
    console.log(
      `${m.name.padEnd(13)} ${String(cap).padStart(8)} ${String(s.accepted).padStart(10)} ${String(s.finalQueue).padStart(10)} ` +
      `${s.wait.toFixed(2).padStart(15)} ${s.reviewDeviation.toFixed(1).padStart(19)} ` +
      `${String(s.localCopy).padStart(13)} ${total.toFixed(1).padStart(16)}`
    );
  }
  rows.sort((a, b) => a.total - b.total);
  console.log(`model producing least deviation: ${rows[0].name} (${rows[0].total.toFixed(1)})`);
}

// Tipping point: up to how many product teams does the centralized model keep up
// without building a queue?
console.log("\nteams   demand   centralized capacity   builds a queue");
for (let team = 2; team <= 8; team++) {
  const demand = DEMAND_PER_TEAM * team;
  const cap = MODELS[0].capacity(team);
  console.log(`${String(team).padStart(5)} ${String(demand).padStart(8)} ${String(cap).padStart(21)} ${(demand > cap ? "yes" : "no").padStart(16)}`);
}

// How much the core's approval capacity changes the outcome in the hybrid model.
console.log("\ncore approval capacity in the hybrid model (12 teams, demand 60, total demand 720)");
console.log("core   effective capacity   accepted     pending   local copy   total deviation");
for (const core of [35, 45, 55, 65]) {
  const cap = Math.min(core, 6 * 12);
  const s = run(cap, 0.70, 60);
  console.log(
    `${String(core).padStart(4)} ${String(cap).padStart(19)} ${String(s.accepted).padStart(10)} ` +
    `${String(s.finalQueue).padStart(10)} ${String(s.localCopy).padStart(13)} ` +
    `${(s.reviewDeviation + s.localCopy).toFixed(1).padStart(17)}`
  );
}
```

```

=== 4 product teams · 20 contributions demanded per period · 12 periods · total demand 240 ===
model         capacity   accepted     pending    wait(periods)   review deviation   local copy   total deviation
centralized         22        240          0            0.00                 4.2             0              4.2
federated           24        240          0            0.00                71.4             0             71.4
hybrid              24        240          0            0.00                25.2             0             25.2
model producing least deviation: centralized (4.2)

=== 12 product teams · 60 contributions demanded per period · 12 periods · total demand 720 ===
model         capacity   accepted     pending    wait(periods)   review deviation   local copy   total deviation
centralized         22        264         44            1.98                 4.6           412            416.6
federated           72        720          0            0.00               214.2             0            214.2
hybrid              55        660         60            0.59                69.3             0             69.3
model producing least deviation: hybrid (69.3)

teams   demand   centralized capacity   builds a queue
    2       10                    22               no
    3       15                    22               no
    4       20                    22               no
    5       25                    22              yes
    6       30                    22              yes
    7       35                    22              yes
    8       40                    22              yes

core approval capacity in the hybrid model (12 teams, demand 60, total demand 720)
core   effective capacity   accepted     pending   local copy   total deviation
  35                  35        420         70           230             274.1
  45                  45        540         90            90             146.7
  55                  55        660         60             0              69.3
  65                  65        720          0             0              75.6
```

## The Outcome Changing with Scale

The two tables run the same three models at two different scales, and the ranking
reverses.

At four product teams, the centralized model gives the best result: all 240
contributions ship, there is no wait, and deviation is 4.2. The federated model does
the same work in the same time, but its deviation is 71.4 — seventeen times higher. At
this scale, the central team's capacity is enough to meet demand; the federated
model's extra capacity buys nothing, only paying the cost of lower review visibility.

At twelve product teams, the centralized model collapses: deviation is 416.6. 412 of
that number is local copies. The central team can only handle 264 of the 720 demanded;
the rest sits in the queue past the wait threshold and teams write their own copies.

This mechanism is the point most governance discussions miss: the centralized model's
cost is **not the wait itself** but the wait turning into abandonment. The central
team's review quality has not dropped at all — its deviation rate is still 4.6, the
lowest value. The system stays good at what it reviews; the problem is that it is not
reviewing most of the work.

The third table gives the centralized model's tipping point: no queue builds up to
four product teams, and one starts from the fifth on. This number is not a rule but the
ratio of this organization's capacity to its demand — enlarge the central team and the
point shifts right. What decides is not the model's name but this ratio.

## Tuning the Hybrid Model

The last table shows how sensitive the hybrid model is to a single parameter — the
core's approval capacity — and it needs to be read carefully.

At a core capacity of 35, the hybrid model is nearly as bad as the centralized one: 230
local copies. At capacity 45, local copies drop to 90; at 55, to zero. The hybrid
model working, in other words, depends on the core approving **fast enough to keep up
with the product teams' preparation speed**. If the core becomes the bottleneck, a
model named hybrid is a centralized model in disguise.

The last row holds a trap: at core capacity 65, total deviation rises to 75.6 — higher
than 69.3 at 55. This does not mean raising capacity is harmful. At 55, 660
contributions have shipped and 60 still sit in the queue; at 65, all 720 have shipped.
Deviation per shipped contribution is the same in both cases — 69.3 over 660 and 75.6
over 720 both equal 0.105. The total looks lower only because part of the work had not
been done yet.

This is a general flaw to avoid when building a measurement: **unmet demand can look
like a success.** Unless the number of contributions shipped and the length of the
pending queue are reported, a system that does no work produces the cleanest-looking
numbers.

## Decisions That Must Stay Centralized

Model choice is not a single switch; each type of decision can be kept centralized or
distributed on its own. The criterion for the split is **how many components a
decision affects at once**.

Decisions that must stay centralized are the ones whose effect reaches beyond
individual components: the token layer's structure, the naming convention, maturity
levels' exit criteria, breaking-change approval, and accessibility criteria. One of
these being applied differently in two teams ends the system's being a system.

Decisions that can be distributed are the ones that stay within a single component:
adding an optional prop to a component, widening a value set, writing doc examples,
designing product-specific components. The classification built in the previous lesson
turns directly into an authorization rule here: **additive contributions are
distributed, breaking contributions stay centralized.**

For this split to work, a third record is needed: **ownership**. Every component must
have a named owner; a component with no owner is reviewed under no model. The
ownership record is part of the catalog and is kept together with the maturity level
defined in the first lesson.

## Summary

- Governance model is a choice between consistency and speed; the three
  arrangements — centralized, federated, hybrid — are defined by the variables capacity
  and review visibility. The centralized model's capacity does not grow with the
  organization; the federated model's capacity grows but its review visibility drops.
- The centralized model's cost is not the wait itself but the wait turning into local
  copies; the system stays good at what it reviews, but it stops reviewing most of the
  work.
- Model choice depends on scale: the same three models favor the centralized model at
  four teams and the hybrid model at twelve. The tipping point is computed from the
  ratio of capacity to demand.
- If the core's approval capacity in the hybrid model does not keep up with the product
  teams' preparation speed, the model turns into a centralized model called hybrid.
- Unmet demand misleads when it is not reported; a low deviation number is deceptive
  unless shipped contributions and pending queue are reported together.
- Decisions are distributed one by one: ones affecting multiple components stay
  centralized, ones staying within a single component are distributed; every component
  must have a written owner.

## Next Step

In this lesson's model, "local copy" was an assumption: it was assumed that a certain
portion of the work waiting in the queue would leave the system. In a real
organization, this number is not assumed, it is measured. The next lesson builds
adoption measurement: it computes the ratio of system component usage to local copies
through a repository scan, derives coverage percentage by team, produces a deviation
list, and shows which local copy points to a component that should enter the catalog.
