A resource for design system leads and their sponsors
Decisionrightstemplate.
Governance that speeds a system up.
One decider. One deadline. No meeting unless the door is one-way.
Most governance is a queue with no owner.
Teams dislike design system governance because they have met it as enforcement: a council that meets every other Thursday, a pull request waiting for four approvals. The essay behind this guide argues the opposite. Governance is decision rights, a change format and release discipline, and done well it is a throughput tool. Agents raise the stakes: a system they build with changes faster, and every change needs someone who can say yes or no.
The models this guide borrows from agree on the core. RAPID names one person who decides [S01], DACI one approver [S02], and the advice process lets the person closest to the work decide after seeking advice [S04]. Bezos adds the sorting rule: reversible decisions should be made quickly [S05].
The template turns that into a file. decision-rights.json gives each type of decision one decider, a deadline in business days, a record and the paths it owns. The kit checks it, generates CODEOWNERS from it and measures time to decision.
Practical guidance, not a standard. People, handles and the decision log in the kit are fictional; time-to-decision figures come from that sample log, not a real team. Prepared with AI assistance and edited by hand.
Start here
One matrix, read by people and by GitHub.
The field names map onto the frameworks your organisation may already use. Pick the vocabulary your sponsor knows; keep the rules.
| This template | RAPID (Bain) | DACI (Atlassian) | RACI | Advice process |
|---|---|---|---|---|
decider, one role | Decide | Approver | Accountable | The person taking the decision |
advisors | Input | Contributors | Consulted | Everyone affected, and experts |
agree, at most one | Agree | none | none | none |
informed | none | Informed | Informed | none |
author (the proposer) | Recommend | Driver | Responsible | Anyone may decide |
Sources: S01, S02, S03, S04. author as decider is this template's advice process, allowed on two-way doors only.
Writing the first matrix
Copy decision-rights.json, list the ten decisions your team made most often last quarter, and give each one decider. Section 01 first.
Unblocking a stalled system
Section 02 and 03: put an SLA on every decision and take meetings off every two-way door. Run the SLA report on last quarter's pull requests.
Opening the system to contributors
Section 03, rule G15. Small contributions stay fast; only new components and removals take the long route.
Enforcing it
Section 04. Generate CODEOWNERS from the matrix and turn on required code-owner review, so the decider is the reviewer GitHub asks.
| Label | Meaning |
|---|---|
MATRIX | A field in decision-rights.json. |
CHECK | Enforced by check-decision-rights.mjs (error or warning). |
CODEOWNERS | Enforced by the generated CODEOWNERS file and GitHub's code-owner review. |
SLA | Measured by sla-report.mjs over the decision log. |
PRACTICE | A working method with a review signal rather than a hard gate. |
Section 01
Name one decider.
One decision, one person who makes it. Everyone else has a voice, and the matrix says whose.
Suggested owners: Design-system lead + sponsor
Every decision type names exactly one decider
"Engineering and design decide together" means nobody decides. One role in
decider, never a list; the rest go inadvisors.Evidence: Checker error
no-single-decideron a missing decider or an array.RAPID: ideally one person per decision [S01]. DACI: one approver [S02]. RACI: one accountable, in some theories [S03].
A committee advises; it never decides
A council, board or guild can advise or be informed. It cannot decide or be the escalation: a group has no one who owns the deadline.
Evidence: Checker error
committee-deciderwhen the decider or escalation is a role withmembersor a group title.Bain allows a group D only with a protocol agreed upfront; this template is stricter. S01.
The decider is a named person with a GitHub handle
A role is a promise; a person keeps it. Name who holds the role today and their GitHub handle.
Evidence: Checker error
no-personwhenpersonis empty orgithubis not a valid@handle.Needed for CODEOWNERS generation. S13.
Every decider has a delegate
Holidays are when SLAs break. Name who decides when the decider is away or the deadline is close.
Evidence: Checker warning
no-delegate; the SLA report accepts the decider or the delegate.Recommended practice.
At most one veto per decision
An
agreerole must sign off, which makes it a veto. Keep it for one non-negotiable constraint, such as accessibility on a new component.Evidence: Checker warning
many-agreeabove one; the schema capsagreeat one item.RAPID: Agree is assigned sparingly. S01.
If two people can say yes, you will wait for both of them.
Section 02
Put a clock on every decision.
Throughput is time to decision. An SLA turns "we are discussing it" into a date, and escalation says what happens when the date passes.
Suggested owners: Design-system lead
Every decision type has an SLA in business days
Count from the day the request is complete to the day the decider says yes, no or not yet with a reason. Business days, so a Friday request is not late on Monday.
Evidence: Checker error
no-slawhenslaBusinessDaysis missing or below 1.Recommended practice.
SLAs have a cap per door
The example caps two-way doors at 3 business days and one-way doors at 10. Tighten them once the report shows you meet them.
Evidence: Checker error
sla-over-capagainstpolicy.maxSlaBusinessDays.Precedents: Apache votes run at least 72 hours [S06]; a Rust RFC's final comment period lasts ten calendar days [S07]. The caps are defaults, not findings.
Advice is sought and recorded, not obeyed
Advisors are asked before the decision and their advice goes into the record. The decider may decide against it, and says why.
Evidence: The ADR template's Advice received table, one row per advisor in the matrix.
The advice process: seek advice from those affected and from experts; it is not binding. S04.
Silence has a meaning
Advisors get an advice window. When it closes without an answer, the record says "no response" and the decider proceeds. Waiting for everyone is how a two-day decision takes a month.
Evidence:
adviceWindowBusinessDayson advice-process decisions; "no response by" rows in ADRs.Apache lazy consensus: silence gives assent. S06.
Escalation goes to one other person
When the decider misses the SLA or a disagreement will not settle, one named role above them decides. Never the decider, never a group.
Evidence: Checker error
no-escalationwhen missing or equal to the decider;committee-deciderwhen it is a group.Recommended practice.
A decision without a date is a queue.
Section 03
Size the door before you open it.
Most design system decisions are reversible. Save the slow process for the few that are not.
Suggested owners: Design-system lead + engineering lead
Every decision type is a one-way or a two-way door
One-way: hard to reverse once consumers depend on it. Two-way: a later release can undo it.
Evidence: Checker error
no-doorunlessdoorisone-wayortwo-way.Bezos, Type 1 and Type 2 decisions. S05.
One-way doors get a written record
An ADR for removals, policy changes and waivers; an RFC for a new component.
Evidence: Checker error
one-way-needs-recordonrecord: "pr". Templates intemplates/.Nygard's ADR sections and statuses [S08]. Curtis uses ADRs to evolve component contracts [S09].
Two-way doors are decided without a meeting
The pull request is the meeting: the decider reads, asks in the thread and decides inside the SLA.
Evidence: Checker error
two-way-meetingwhen a two-way door hasmeeting: true.Bezos: reversible decisions made quickly by individuals or small groups. S05.
The author decides small, reversible changes after seeking advice
Docs fixes need no decider but their author, who asks the docs owner and merges within a day.
Evidence: Checker error
author-misuseunless the door is two-way, with advisors and a short advice window.The advice process: anyone can decide, after seeking advice. S04.
Small contributions stay fast; new components take the long road
Fix, small enhancement, large enhancement, new component: only the last goes through proposal criteria.
Evidence: D01 and D02: 1 and 2 business days, PR only. D06: an RFC, 10 business days.
Curtis's contribution sizes [S10]; GOV.UK proposal criteria [S11]; Frost's governance process [S12].
No RFC for a reversible change
Run the one-way process on two-way decisions and every prop becomes a proposal.
Evidence: Checker warning
heavy-two-wayon a two-way door withrecord: "rfc".Bezos: heavy-weight process on Type 2 decisions leads to slowness. S05.
Save the slow process for the doors you cannot walk back through.
Section 04
Wire the matrix into the repository.
A decision-rights page on a wiki is advice. CODEOWNERS makes GitHub ask the decider on every pull request that touches their paths.
Suggested owners: Engineering lead
CODEOWNERS is generated from the matrix
Each decision's
pathsbecome CODEOWNERS lines with the decider and the delegate. Require code-owner review in branch protection. Any one owner on a line can approve, so agree when the delegate acts.Evidence:
generate-codeowners.mjs decision-rights.json --check .github/CODEOWNERSfails in CI when the file drifts.GitHub: the last matching pattern wins; one approval from any listed owner satisfies required review. S13.
One path, one decider
Two decisions may share a path only if they share a decider. Otherwise CODEOWNERS would silently pick whichever line comes last.
Evidence: Checker error
path-conflict; the generator refuses a matrix with errors.GitHub: the last matching pattern takes precedence. S13.
One-way doors are routed by the file they cannot avoid
CODEOWNERS cannot tell a fix from a removal in one folder. Route one-way decisions through files only they change:
src/index.tsfor new exports,token-renames.jsonandmigrations/for removals.Evidence: D06, D07 and D09 in the example matrix own exactly those paths.
Field Guide 03, rule R24: every removal appears in the migration map.
Author-decided paths have no required owner
A pattern with no owners removes broader owners for that path, so docs fixes need only the normal review.
Evidence: The generated file lists
/docs/with no owner and/docs/deprecation-policy.mdafter it with the design system lead.GitHub: without an owner, anyone with write access can approve. S13.
Only patterns GitHub supports
CODEOWNERS follows most gitignore rules but not negation with
!, character ranges with[ ]or escaping with a backslash. Invalid lines are skipped silently.Evidence: Checker error
bad-pattern.GitHub CODEOWNERS syntax exceptions. S13.
If GitHub does not know who decides, nobody else will remember.
Section 05
Run it, and measure time to decision.
The matrix is a hypothesis about how fast your system can move. Pull requests carry it; the decision log tests it.
Suggested owners: Design-system lead + release owner
Every pull request names its decision
The template asks for the decision type, the decider and the due date, and links the ADR for one-way doors. Reviewers, and agents opening pull requests, classify the change before anyone reviews it.
Evidence:
templates/pull_request_template.mdcopied to.github/.Recommended practice.
The matrix governs itself
Changing who decides is a one-way door with its own decider, usually the sponsor. The matrix file and CODEOWNERS are routed to that person.
Evidence: D10 in the example matrix owns
/decision-rights.jsonand/.github/CODEOWNERS.Recommended practice.
Log every decision with opened and decided dates
One line per decision: id, decision type, title, opened, decided, decided by. Pull request timestamps and ADR dates are enough; the log can be generated from them.
Evidence:
decision-log.jsonin the shape of the kit's example.Recommended practice.
Report breaches and overdue decisions every week
Median and slowest time per decision type, breaches against the SLA and open decisions past their due date. Overdue items go to the escalation role, not to a meeting.
Evidence:
sla-report.mjsexits 1 when anything is overdue or decided by the wrong person.Kit script.
Decisions by the wrong person are defects in the matrix
When the council decides what the engineering lead owns, either the matrix is wrong or the team is not using it. Fix whichever it is at the next quarterly review.
Evidence: The report's WRONG DECIDER lines; a quarterly ADR under D10 when the matrix changes.
Recommended practice.
Governance is working when decisions are boring and fast.
Appendix A
The Acme matrix.
Twelve decision types from decision-rights.json. The checker reports 0 errors and 0 warnings on it. People and handles are fictional.
| ID | Decision | Door | Decider | SLA | Record | Owns |
|---|---|---|---|---|---|---|
| D01 | Fix a defect with no API change | two-way | eng-lead | 1 | PR | /src/components/ |
| D02 | Add an optional prop or enum value | two-way | eng-lead | 2 | PR | /src/components/, /contracts/ |
| D03 | Change a semantic token value | two-way | token-owner | 2 | PR | /tokens/semantic/ |
| D04 | Add or deprecate a semantic token | two-way | token-owner | 2 | PR | /tokens/semantic/ |
| D05 | Correct or extend documentation | two-way | author | 2 | PR | /docs/ |
| D06 | Add a component to the public API | one-way | ds-lead | 10 | RFC | /src/index.ts |
| D07 | Remove or rename anything public | one-way | ds-lead | 5 | ADR | /token-renames.json, /migrations/ |
| D08 | Deprecate a component or prop | two-way | eng-lead | 3 | ADR | none |
| D09 | Change the deprecation policy or cadence | one-way | ds-lead | 10 | ADR | /docs/deprecation-policy.md |
| D10 | Change these decision rights | one-way | sponsor | 10 | ADR | /decision-rights.json, /.github/CODEOWNERS |
| D11 | Cut a release | two-way | release-owner | 1 | PR | /CHANGELOG.md |
| D12 | Waive an accessibility requirement | one-way | a11y-lead | 3 | ADR | none |
SLA in business days. D06 also names the accessibility lead as its one agree role. Deprecation is a two-way door; removal is not.
Appendix B
What the checker catches, and what GitHub gets.
examples/decision-rights.violations.json is a first draft of the same matrix with the usual mistakes. The checker exits 1 with 13 errors and 4 warnings.
terminal
$ node scripts/check-decision-rights.mjs examples/decision-rights.violations.json
decision-rights.violations.json: 4 decisions, 13 errors, 4 warnings
error D01 no-single-decider: 2 deciders listed; name one
error D02 committee-decider: decider "ds-council" (Design system council)
is a group; name the one person who decides
error D02 sla-over-cap: 10 business days is over the two-way cap of 3
error D02 two-way-meeting: two-way doors are decided without a meeting
error D03 bad-pattern: "!/tokens/semantic/dark.tokens.json" uses syntax
CODEOWNERS does not support (!, [ ], \ or leading #)
error D07 one-way-needs-record: a one-way door needs an ADR or RFC, not
only a pull request
error D07 path-conflict: "/tokens/semantic/**/*.json" is also claimed
by D03 (token-owner); one path, one decider
... 6 more errors
warning D02 heavy-two-way: an RFC on a two-way door slows a reversible
decision
... 3 more warningsOutput from the kit, wrapped for print and shortened. The full run is in the kit's tests.
examples/CODEOWNERS (generated, excerpt)
# Generated from decision-rights.json (Acme Design System, matrix 1.0.0)
# by generate-codeowners.mjs. Do not edit by hand.
# GitHub uses the last matching pattern, so broader patterns come first.
# D05 two-way, 2bd. The author decides after seeking advice from:
# Docs owner. No required owner.
/docs/
# D01 two-way, 1bd; D02 two-way, 2bd. Decider: Design system
# engineering lead (Mikko Laine), delegate Aino Virtanen.
/src/components/ @mikko-laine @aino-virtanen
# D09 one-way, 10bd. Decider: Design system lead (Aino Virtanen),
# delegate Mikko Laine.
/docs/deprecation-policy.md @aino-virtanen @mikko-laine3 of 11 patterns; comment lines wrapped and the header shortened for print. Pass --no-delegates to list deciders only.
Appendix C
Time to decision, from the log.
The kit's sample log holds 17 fictional decisions from July to September 2026. It is there to show the report, not to benchmark anything.
terminal
$ node scripts/sla-report.mjs decision-rights.json examples/decision-log.json --as-of 2026-09-24
Decisions as of 2026-09-24: 17 logged, 15 decided, 14 within SLA.
Median time to decision on two-way doors: 1 business day.
Type Door SLA Done Open Median Slowest Breaches
D01 two-way 1 2 0 0.5 1 0
D02 two-way 2 3 0 2 4 1
D03 two-way 2 1 1 1 1 0
D06 one-way 10 1 1 9 9 0
D07 one-way 5 1 0 4 4 0
D08 two-way 3 1 0 3 3 0
OVERDUE DR-2026-057 (D03) "Raise color.text.muted contrast": due 2026-09-23,
1 business day(s) late
OVERDUE DR-2026-056 (D06) "Add Toast": due 2026-09-15, 7 business day(s) late
WRONG DECIDER DR-2026-050 (D08) decided by ds-council; the matrix names eng-lead6 of 10 rows shown. The report exits 1: two decisions are overdue and one was made by a group the matrix does not name.
templates/adr.md (headings)
# ADR-NNNN: <short noun phrase>
- Decision type / Door / Status / Decider / Opened / Due / Decided
## Context
## Options considered
## Advice received (one row per advisor in the matrix)
## Decision ("We will ...", active voice)
## Consequences
## Follow-up (contract, migration map, changelog, log entry)Nygard's five parts, plus the advice table the advice process needs and the dates the SLA report reads.
Keep with the matrix
Leave a quarterly review record.
One record per quarterly review of the matrix. It is the trail that shows why a decision moved, or why an SLA changed.
Sources / maintenance
Keep the guide current.
Checked 24 September 2026. SLA precedents are open-source governance, not design system benchmarks.