Most teams treat a UI bug as a bug in the app they noticed it in. Wrong layer. The bug lives where the source of truth lives, and most of the time that is the design system, not the consuming app. The same discipline applies to AI: fix the prompt at the central skill layer, not at every consuming agent.
The default move that wastes a week
When a teammate flags a UI bug on an app, the orthodox path is to log it against that app. Description, repro steps, screenshot, ticket. Assigned to the team that owns the app. Resolved by patching the rendering in that app's codebase.
That path feels precise because it is local. Local feels diligent. Local feels accountable. You touched one file. You fixed one symptom. The ticket closes.
It is also wrong, most of the time. Most UI bugs I find on the consuming app are really design-system bugs in disguise. Patching them at the app layer is a tax you pay per app per occurrence, and the same bug will reappear in three other places next quarter because the actual cause lives somewhere you did not look.
The layer trace as a sourcing discipline
Before logging anything, ask one question. Does this bug live at the consuming app layer, or does it live at the design system layer that the app pulls from.
That question is the layer trace. It takes thirty seconds. It changes where the work happens.
A bug logged at the app layer is patched once. A bug logged at the design system layer is fixed for every app that consumes it. Same fix. Different surface. Different blast radius.
I just ran a second full structured audit of an app's 2.0 surface, page by page. Same correction pattern over and over. I would catch myself flagging a UI bug at the app layer, then interrupt myself and say, wait, this should be fixed at the design system, not here. Same self-correction, three or four times in the same hour. After the third one, the layer trace stopped being an interruption and started being the first thing I did.
That is the whole discipline. One question, asked before the ticket exists.
The shape of the bug determines the layer
Most layer-trace calls are not ambiguous once you have the question on the table. The shape of the bug tells you the answer.
Camel-cased labels in a sort dropdown. That is a token formatting concern. Lives in the design system.
Missing disabled cursor on a button. That is a base interaction state. Lives in the design system.
A chip styled like a button so users keep trying to click it. That is a visual ambiguity between two base components. Lives in the design system.
A dropdown menu with no minimum height that collapses to a single-pixel sliver when there is one option. Same shape. Design system.
Then the other side of the line.
Missing per-variant test cases on a dynamic table grouped by brand. That is the consuming app, because the variant is the composition the app builds out of the base table. The table itself is fine. The app's choice to use it grouped, pinned, with this specific filter shape, is what is missing tests.
A specific report page failing to wire its currency dropdown into a real currency context. That is the consuming app. The dropdown component is doing its job. The wiring is the app's responsibility.
The discipline is showing both kinds in the same audit and naming the layer for each. The audit itself stops being a bug list and starts being a sourcing map. Same artifact. Different output.
The same discipline maps to AI systems
This is where the post stops being about UI bugs.
Most AI workflows ship with prompts living inside every consuming agent. The agent that drafts a report has its own prompt. The agent that summarizes a meeting has its own prompt. The agent that critiques the draft has its own prompt. Twelve agents, twelve prompts, twelve forks of the same baseline voice rules.
When the voice rules need to change, the orthodox path is to update each agent. Twelve diffs across twelve repos. A week of work. Drift between them by the end of the month because somebody missed agent number seven.
Stop patching prompts in every agent that calls them. Prompts are the design tokens of an AI system. The voice rules. The output shape. The guardrails about what the model will and will not do. Those belong at a central skill layer the consuming agents inherit from.
Centralize the skill. When the voice rule changes, every consuming agent inherits the fix. When the skill lives in twelve forks, you patched the symptom in twelve places and the root cause is still there, waiting to bite the next time you need to change anything about how the system speaks.
Same layer trace. Different surface. The question is the same: does this prompt issue live at the consuming agent, or at the skill layer that the agent pulls from.
The economics
A design system fix cascades to every app for free. The fix has a one-time cost. The cascade is the payoff.
An app-layer fix is a tax. You pay it once per app per occurrence. Three apps, three taxes. Twelve apps, twelve. The cost scales linearly with how many surfaces consume the broken thing.
The same math holds for prompts. A skill-layer fix cascades to every agent that inherits. An agent-by-agent fix is a tax that scales with how many agents you have. The bigger the agent fleet, the more painful the tax becomes, and the more invisible it gets because nobody is tracking the per-agent patching as a line item.
The first time you do the layer trace, it feels slower because you are not just fixing the thing in front of you. You stop, ask the question, decide the layer, often have to write a more careful fix because the design system version has to handle every consuming case, not just the one you noticed.
By the third audit, it is the only thing that compounds. The local fixes pile up linearly. The source-of-truth fixes pile up exponentially. After six months, the team that did layer traces has a system that is getting cleaner. The team that patched at the app layer has a system that is getting more entangled with itself.
That is not a discipline difference. That is a where-the-fix-lives difference.
When the layer trace tells you no
The discipline cuts both ways. Sometimes the layer trace says the bug really does live in the consuming app, and the right call is to fix it there.
A specific report page where the data wiring is wrong. The chart legend cluttering at a screen size that only matters on that page. A button placement that only makes sense in the context of one specific user flow. Those are app-layer bugs. Logging them against the design system would be wrong in the other direction.
The point is not to default everything to the design system. The point is to ask the question. Defaulting everything to the app is lazy. Defaulting everything to the design system is lazy in the other direction. The discipline is the trace, not the destination.
The closer
When a bug shows up, ask the layer question first. Where does this actually live. The right answer is almost never the layer where you noticed it.
The same question works for prompts. The same question works for the next layered system that has not been invented yet. Source-of-truth discipline is not a UI rule. It is a sourcing rule that happens to show up first in UI work because design systems make the layers visible.
Fix the source. The symptom takes care of itself.

