Case Study  ·  Knapsack

Making deletion trustworthy

Role  UX Engineer (2024 to 2026), after two years as Solutions Architect
Scope  Owned the design system. Led the destructive-action overhaul across the platform.

Knapsack is an enterprise design system platform, and every place it let someone delete something behaved differently. I audited all 18 destructive actions, cut them down to three patterns, and shipped the result as a typed utility that will not compile unless the next engineer answers the same two questions I did.

One question sorted all 18. What are the stakes, and can the person recover? Confirmation dialogs on everything punish people for routine work. Undo on everything is a lie for things that can't be restored. Match the friction to the stakes instead, and three patterns cover the platform.

Pattern 01

Inline confirm

Low stakes, deliberate and rare. The confirmation lives inside the menu itself. Structural items like collections, groups, and modes.

Pattern 02

Modal

High stakes, no way back. A full stop that interrupts on purpose, for deletions that are rare and irreversible.

Pattern 03

Toast with undo

Frequent and recoverable. No confirmation at all. The easy way back is the safety. Pages, nav items, attachments.

Knapsack's product screens are under NDA, so these are the three patterns rebuilt as working demos. Click around. They behave like the shipped versions.

Making it the default

I rolled the patterns out across the platform myself. Then I built the shared utility every other engineer now uses, and that is the piece that matters. It won't let anyone build a destructive action without answering the two questions from the audit. Answer them and the right pattern comes out. Skip them and TypeScript refuses to build.

That's the difference between a guideline and a default. A guideline asks every engineer to remember a decision I made once, on a surface I will never review. A default makes the correct thing the easy thing and the wrong thing fail before it reaches a person. The judgment moved out of my head and into the compiler, where it holds without anyone having to remember it.

The audit also caught what the happy path hides. Delete actions that ignored read-only permissions, destructive buttons styled like safe ones, deletions with no warning about downstream impact. Fixing a pattern means fixing its edges.

The rest of what I owned

I owned the design system itself, its components, its updates, its releases. Anyone could propose a change and nothing landed without a named person signing off, which was me. Low barrier to contributing, real barrier to landing. Drop the first and people route around the system. Drop the second and it stops being one.

The same shape solved our token bottleneck. Changing a variable meant waiting on a developer to translate it into code, so I set our product designer up in Tokens Studio to commit token updates directly, with a developer still approving before anything distributed. Days out of every token change. The gate stayed, the queue disappeared. We handed the same pipeline to customer teams when it fit how they worked.

Before that I taught Fortune 1000 teams in fintech, healthcare, and aerospace to run their own systems. Owning one and teaching someone to own theirs fail the same way, because one person becomes the only one who understands it. So the work that mattered most in both jobs was the least visible part, writing the thing down and then getting out of the way.

The audit that became Plumb

Before Plumb existed, I was doing it by hand.

I kept a living page comparing our Figma files against what we actually shipped, component by component. A data table got eleven rows. An action menu got seven. Every row held three things: what the design specified, what the code did, and which one was right.

Most mismatches were not bugs. A border token resolved to a grey a few percent off the one the design called for, close enough to look identical and far enough apart to need an answer. Header dividers existed in code and not in the design. A menu was pinned to a fixed width where every other menu in the app sized to its content.

The interesting rows were the ones where the code won. Figma had clipped a column header to “Up” because the row was too short to fit “Updated,” and the build showed the whole word. Figma styled a delete action in the default text color, and the build shipped it red like every other delete in the product. Twice the file was wrong and the code was right.

That is the part people skip. A drift report that always blames the code is not a report, it is a preference. Every row got a verdict and a reason, and the verdict went whichever way the argument went.

Then I proposed the process. Keep the page alive, run a diff after each feature ships, review it together on a recurring cadence.

Plumb is that page, automated. Same three columns, same rule that a person decides each row. All I added was a model to draft the rows and a confidence score to say how sure it is.

Why this is the same project as Plumb

Deletion UX and agent approval are one problem. An action with consequences is about to happen, and a person needs the right amount of friction, not the maximum amount. I got to design that for humans at Knapsack. Plumb is what happened when I started designing it for AI agents.