Design Systems · 5 min read
The Build Is the Gatekeeper
If a machine can check an icon rule, it should block the merge. That frees the human gatekeeper for the one job a build cannot do: judging meaning.
Most design-system rules live in a document. A contributor reads it once, maybe. A reviewer remembers some of it on a good day. Then an icon ships with no accessible name, a status color a shade too light, and a name nobody can find in the library. Nobody broke a rule on purpose. The rule just wasn't standing in the way.
A rule that does not block is a suggestion
Software teams solved this years ago. On GitHub, a protected branch can require status checks. Once that is on, "all required status checks must pass before collaborators can merge changes into the protected branch." A failing check is not a comment someone can skim past. The merge button stays shut.
Design rules can work the same way. A status check is any script that runs on every proposed change and returns pass or fail. If an icon rule can be written as a script, it can block a merge exactly like a failing unit test.
My position: every icon rule a machine can check should block the merge. The human gatekeeper keeps only the judgments a machine cannot make.
A gatekeeper’s review is most valuable when it can focus on meaning: does the icon say the right thing, and would a new user understand it?
What a machine can check
More than most teams think. Appendix B.7 lists five gates for an icon build. Each one has a clear pass or fail.
- **The name exists.** If the manifest is typed in TypeScript, a misspelled icon name fails to compile. It never reaches production as a blank square.
- **Every icon is labelled or declared decorative.** A lint rule can refuse an icon that is neither. Deque's axe-core already ships a related check, svg-img-alt, for SVGs given an image role. It maps to WCAG 1.1.1 and rates a miss as "serious."
- **Status colors meet contrast.** WCAG 1.4.11 asks for at least 3:1 between a meaningful graphic and the colors next to it. W3C's guidance names stand-alone icons as graphical objects and says the ratio is not rounded: 2.999:1 fails. A script can test every status token against every surface it sits on.
- **Small sizes have a real drawing.** If the system requires a hand-drawn 16 px master, the build can check that the file is there.
- **New symbols carry evidence.** A new root cannot ship without a comprehension test record linked in the manifest.
Notice what the last gate does. It cannot judge the test. It can only refuse to go on until a test exists. That is a useful pattern: the build checks that a human decision was made, without pretending to make it.
What it cannot check
Here is the strongest case against gates. Automated checks find less than people assume, and passing them feels like being done.
In 2017 the UK Government Digital Service built a web page with 143 accessibility failures and ran 10 automated tools against it. Together the tools found 71 percent. The best single tool found 37 percent counting errors and warnings, or 41 percent if you count its prompts for manual checks. Forty-two failures, 29 percent, were missed by every tool. The team's conclusion: tools "cannot be relied on, by themselves," and work best "combined with manual testing."
The icon case is sharper. The axe rule tests whether an SVG has a non-empty title. It does not know whether the title is true. A trash can labelled "Archive" passes. A warning triangle labelled "icon" passes. A gate can prove a label exists. It cannot prove the label means what the drawing means.
Gates also invite workarounds. GitHub's own documentation says that by default, branch protection rules "don't apply to people with admin permissions," unless a team turns on the setting that stops bypassing. A gate that fails for bad reasons teaches people to go around it.
Why the position holds anyway
Both objections are real. Neither one argues for keeping the rules in a document.
The GDS numbers say tools miss close to a third of problems. They also say tools caught most of them, every time, at no cost to anyone's attention. That is the trade. Without gates, the reviewer spends the review hunting for missing labels and light colors, and has no time left for meaning. With gates, the reviewer starts where the machine stopped.
GitHub's Octicons team showed a good version of this split in 2018. Their icons moved to Figma as the source. On every pull request, continuous integration exported the icons and published alpha versions of the libraries. A bot then commented on the pull request "with before and after images." The machine did the export and the rendering. People looked at pictures and judged them.
So the gatekeeper does not disappear. The job changes. The person stops checking files and starts checking meaning. Is this the right root? Does this compound read as one idea? Would a stranger name it? Only a person can answer those, and they were always the questions worth the gatekeeper's time.
Three habits keep gates honest:
1. Every check fails with a message that says how to fix it. 2. The no-bypass setting is on, so admins meet the same gate as everyone else. 3. When a gate blocks something correct, fix the gate the same day, before people learn to ignore it.
Icon lens
A grammar is a set of rules you can check. Panini wrote Sanskrit grammar as rules, not as a list of approved sentences, and that is why it could be taught and applied. Digital Sanskrit works the same way, and its rules split cleanly into form and meaning. Form belongs to the build: a Severity (tivrata) modifier must come with its status token, a passing contrast ratio and words in the accessible name. The frame carries the mood; the symbol carries the noun. The build can check the frame on every change. Whether the noun is right, whether this root is the one a reader will name, stays a human call, backed by a comprehension test.
Try this
**Goal:** Turn five of your icon rules from documentation into checks that block a merge.
**Steps:**
1. List every icon rule in your design-system docs. Mark each "machine" if a script could return pass or fail, or "human" if it needs judgment. 2. Pick five machine rules. Write each as a one-line test, for example: "Fail if any status color is below 3:1 against any surface token it sits on." 3. For each test, write the failure message a contributor will see, including how to fix it. 4. Run the five checks by hand on your last ten icon changes. Count how many would have been blocked. 5. Move the human rules into a short review checklist about meaning only.
**Check:** Every rule now lives in exactly one place: a blocking check or the meaning checklist. None remain only as prose.
**Reference:** Digital Sanskrit, Appendix B.7, section 6 (The build and its gates), and Appendix A.9 (Accessibility and proof of comprehension).
Sources
- [About protected branches (GitHub Docs)](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches)
- [Understanding SC 1.4.11 Non-text Contrast (W3C WCAG 2.2)](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html)
- [SVG images and graphics require accessible text (Deque, axe 4.4 svg-img-alt)](https://dequeuniversity.com/rules/axe/4.4/svg-img-alt)
- [What we found when we tested tools on the world's least-accessible webpage (GOV.UK, 2017)](https://accessibility.blog.gov.uk/2017/02/24/what-we-found-when-we-tested-tools-on-the-worlds-least-accessible-webpage/)
- [Using Figma designs to build the Octicons icon library (GitHub Blog, 2018)](https://github.blog/engineering/user-experience/driving-changes-from-designs/)