What you’ll learn
A hard-coded value or an overridden component is often just an oversight. But when several teams keep overriding the same component in the same way, the library is probably missing a real use case. That’s useful feedback, and a score alone can’t tell you which case you’re looking at.
ds-bridge watches for deviations that keep coming back across your recorded runs, and turns each one into a conversation with a clear owner: does the implementation need fixing, or should the component evolve?
This tutorial is for design-system managers and designers who look after a Figma library.
- What counts as a recurring exception, and where it shows up
- How to give each one an owner and a decision
- What overdue, resolved and not-seen mean
- Why logging an exception never improves the score
Setup
You’ll need the ds-bridge plugin, a connected Figma library, and at least two recorded library-health runs. A deviation has to show up more than once before it counts as recurring.
ds-bridge library-health # or: ds-bridge record --figma
Each run saves the top components for each signal (override hotspots,
deprecated components still in use, likely detached instances) to
.ds-bridge/history.jsonl. Run it again after a week of work, or let
CI record it for you.
Steps
-
Review the queue. In Claude Code, run the slash command. It lists every recurring exception, the ones still waiting for an owner first:
/ds-bridge:exceptions ds-bridge report --artifacts exceptions-review --open # the same, as a pageA component is listed when it shows up on two or more recorded runs and isn’t back to zero. A one-off deviation is left out on purpose.
-
Read each row as a question, not a fault. A row with no owner asks the question that fits its signal:
- Overrides: fix the usage, or evolve the component?
- Deprecated: migrate off it, or does the replacement miss a use case?
- Detached: re-attach it, or does the component miss a use case?
The answer usually comes from talking to the team that made the change. The tool’s job is to show you where that conversation needs to happen.
-
Log the owner and the decision. Add an entry to the
exceptionsarray in.ds-bridge.json./ds-bridge:exceptionsdrafts it for you and edits the file only after you confirm.{ "exceptions": [ { "component": "Card", "owner": "@checkout-design", "decision": "evolve-component", "note": "Needs a compact layout for order lists", "review_by": "2026-11-15" } ] }decisionis one ofinvestigating,fix-implementationorevolve-component.noteandreview_byare optional. Add"signal": "overrides"(ordeprecated,detached) to scope an entry to one signal. Without it, the entry covers all three for that component. Because the file is committed, the decision is reviewed in a pull request like any other change. -
Keep the queue current. Each later run updates the state of every entry:
- Overdue: the
review_bydate has passed and the deviation is still there. Pick a new date or a new decision. - Resolved: the component’s count is back to zero. Remove the entry.
- Not seen: the name matches nothing that was recorded, usually a typo.
- Overdue: the
-
Share it. The Recurring exceptions panel is part of the dashboard and the ds-designer and ds-manager views. It is also in
ds-bridge report --format json, so it travels with everything else.
Result
- Legacy Buttonneeds an owneroverrides · 1 latest · 2 of 2 runsfix the usage, or evolve the component?
- Legacy Buttonfix the implementationdeprecated · 1 latest · 2 of 2 runs@acme-design · review by Oct 31 · “Swap the last instance for Button”
Recurring deviations are no longer a number to argue about. Each one has an owner, a decision and a date, stored in your repo next to the code.
Troubleshooting
- The panel says No data yet? It needs at least two library-health runs
with stored top-N lists. Run
ds-bridge library-healthagain after some changes. - A component I expected isn’t listed? It may have appeared only once, or
dropped back to zero. Only the top components per signal are stored (10 by
default). Raise it with
ds-bridge library-health --top 25. - My entry shows not seen? Check the spelling against the name in the Library hotspots trend panel. Matching ignores case and surrounding spaces, but not other differences.
reportexits with code 2? The message names the bad field, for exampleexceptions[0].decision must be one of investigating | fix-implementation | evolve-component.