Governing Design Drift
Three plugins that put one source of truth in front of designers, in whatever surface they already work in.
In short
The design system was in good shape, with tokens flowing out of the design tool and tooling that caught drift after it shipped. The problem was that drift kept growing anyway, because every tool found it after the fact. I built three plugins around one idea: put a single source of truth in front of designers, in whatever surface they already work in, with a reviewable diff and a human approve-or-reject on every change. The same loop runs in the design tool, in the component workshop, and in the terminal.
Walkthrough
What problem existed?
The design system was solid: dozens of components, tokens flowing straight out of the design tool, and tooling that caught drift after it shipped. The problem was that drift kept growing anyway. Every tool found drift once it was already in production, and nothing stopped the next raw component or off-token color from being written tomorrow.
As AI makes interface cheaper to produce, that gap widens. More UI, written by more people and more agents, moves faster than after-the-fact detection can keep up with.
Why did it matter?
Catching drift after it ships is the expensive place to catch it. The leverage is upstream, at the moment a designer or an agent makes a choice, where the system can show what is canonical and let a person confirm before it spreads.
It also shifts what design does. Instead of policing output, design can shape the source of truth that everything else reads from. That is a higher-leverage place to stand as creation speeds up.
What constraints existed?
The work was exploratory, with no product team behind it:
- No dedicated team or roadmap.
- An existing design system, token spec, and component workshop to build on.
- The team’s drift-detection tooling already in place, finding drift after the fact.
- Rapidly evolving AI capabilities, and real uncertainty about what governance should become.
The goal was learning and a proof, enough to ask for the go-ahead to keep building.
What role did I play?
The front-end team had built the foundation: the design system, tokens flowing out of the design tool, Code Connect linking design to code, and tools that detect drift after it ships. I built three plugins on top of that, each putting the system’s source of truth in front of designers in a different surface.
One of the three builds on a diff the team had already written to find where a design file disagrees with the spec. My part there was the interface that surfaces it: the panel a designer actually uses to review each difference and decide. Asynchronous teamwork, their diff, my surface for it. The other two I built end to end.
What options were explored?
The three plugins share one mechanism: a source of truth in code, projected onto a surface, where any change shows up as a diff that a person approves or rejects before it counts. Nothing changes silently.
Each plugin covers a different direction of the same relationship.
A production mirror
It reads the system as it shipped, from the component stories and the live app, and draws the real components into the design tool. A scan flags where the app reached past the system: a raw framework component where a system one exists, an inline override. The design tool becomes a snapshot of production, redrawn each run. It reports where things actually stand.
- Dialog raw component, no system equivalent used 4 files → Modal
- TextField raw component used directly 7 files → InputField
- Card inline style overrides system spacing 2 files
A reconcile-and-review panel
A design file drifts from its spec over time. The team had built the diff that finds those differences; I built the panel that surfaces it. A designer walks every change, token by token and component by component, and approves or rejects each one with a reason. The decisions are recorded as receipts, in the frame name and in the file, so the next person, and any later tooling, can read what was decided.
A command-line design system
The same loop, running in a surface that is not a design tool at all: a design system for a command-line tool. One spec generates the building blocks, projects them into the design tool, and, when a designer changes something, shows a diff to apply or set aside. It also checks new patterns against a machine-readable ruleset before they are accepted.
- [SHAPE-01] declared shape "success" recognized
- [HEADER-01] action header present
- [SUCCESS-01] ✓ result rows present
- [BANNER-01] close banner present
Aggregate counts only, no per-repo status rows. The rules confirm the shape and surface the gap; the author decides whether to refine before contributing it back. Nothing here blocks a product team from shipping.
Read together, the point is that governance does not have to live in the design tool. The same source of truth and the same reviewable diff can render wherever people already work: the design tool, the component workshop, or the terminal.
What tradeoffs were considered?
The sharpest tradeoff was automation versus human judgment. The loop automates the detection and the surfacing, but every change still gets a human yes or no, recorded with a reason.
The second was one tool versus everywhere else. It would have been simpler to build this as a feature inside the design tool. Keeping the source of truth in code, and treating the design tool as one surface among several, is what let the same review render in the component workshop and the terminal.
How did UX, engineering feasibility, and business strategy intersect?
The plugins reused what already existed: the token spec, Code Connect, the team’s diff, and the component workshop, so there was no new platform to fund. UX gained a single, legible place to see and decide on change. The business case is that moving review upstream, to the moment of the change, is cheaper than catching drift after it ships and chasing it down later.
How was AI used in the process?
AI showed up on both sides. It is part of why the problem matters, since agents now write UI code too, and they can read the same source of truth a designer does. It was also a tool in the build: I used it to move quickly from idea to a working plugin, and to wire each plugin to the spec and to the team’s diff.
Each plugin was directed the same way, from the spec and the shipped code toward a working surface. Three representative prompts, one per plugin:
The production mirror, built against the shipped system:
Read the component stories and the running app, and generate a
design-tool file that redraws each shipped component from the
system. Then scan the app for places it reached past the system:
a raw framework element where a system component exists, an
inline style override. List each gap with the system equivalent
to use instead. The reconcile panel, wrapped around the team’s existing diff:
Here is the team's diff that finds where a design file disagrees
with the token spec. Build the review panel around it: walk every
difference, token by token and component by component, let me
approve or reject each with a reason, and write each decision
back as a receipt in the frame name and the file. The command-line design system, from a single spec:
From this one spec, generate the command-line system's building
blocks and project them into the design tool. On re-run, diff any
change a designer made and let me apply it or set it aside.
Before a new pattern is accepted, check it against the
machine-readable ruleset and report what fails. The rules and the person made the decisions. AI accelerated the work but never governed the outcome.
What was learned?
The surface is incidental. Once the source of truth lives in code and every change runs through a reviewable diff, governance can render wherever people already work, and the design tool stops being the place decisions have to happen.
Visibility comes before enforcement, which is why one of the plugins is a pure mirror with no gate at all. Knowing what exists and where it has drifted is the precondition for deciding anything about it.
What was the outcome?
Three working plugins that prove one loop end to end, across three surfaces: a mirror that reports how the app uses the system, a panel that reconciles a design file against the spec, and a command-line design system that publishes the spec and reviews changes in the terminal. All of it ran against the real design system and real product code.
The specific implementations will change, but the approach holds: a design system can move review upstream and out of any single tool, so the same source of truth governs everywhere it is used.
A note for teams that have to make the case
My organization does not need convincing to invest here, but plenty of teams do, so this is offered for them. If design-system work is hard to fund where you are, here is a framing that tends to land. Position it as a window into the organization’s bigger picture: the components, frameworks, and dependencies a design system touches are exactly where modernization needs, technical debt, and ownership gaps surface. Presented as that kind of entry point, rather than as housekeeping, the work reads as leverage on problems leadership already cares about, which is usually what earns the attention and investment.