reLabsArticle

From Handoff to Feedback Loop

19 14 min read
From Handoff to Feedback Loop

How we stopped designing against pictures of Humanely and started designing against the situations it would have to survive.

Loizing Singha, Founding Product Designer at Reveriext, working across product design, information architecture, design systems and frontend on Humanely.


You finish a design. It gets reviewed, someone leaves a couple of comments, it gets approved, and it goes to engineering. A while later you open the build and something is off. Not broken. Off. You look for the mistake and can't find one. The spacing is right. The states are all there. Nothing in the file was wrong, and the thing built from it still doesn't feel like the thing you designed.

I used to treat that as a fidelity problem. The build hadn't matched the file closely enough yet, and one more QA pass would close the gap. Building Humanely convinced me I had the direction backwards. The file was the thing missing detail, not the build. Looking back, the change we ended up making wasn't really from Figma to code. It was from designing representations of the product to designing the situations the product would have to survive.

Who this is for: product designers, design engineers, and product leads deciding how much of their process should live in a design file.

What it assumes: you've shipped software through a design-to-engineering handoff, and you know roughly what an AI coding tool does. No code required to read this.

01. The handoff

The traditional process isn't stupid. A design file gives a team a shared visual language and something to argue about before anything is expensive. Engineering gets a spec instead of a vibe. QA gets something concrete to check against.

The trouble is what the file can't hold. It carries hierarchy, composition and tone well. It can't carry how long something takes, what waiting feels like, or what happens when the data is missing or embarrassingly long. Those decisions get made anyway, usually during implementation, by whoever is closest to the code that afternoon. Nobody chose that. It's just where the undesigned parts land.

fig-01-handoff-light.pngFIG. 01. A design describes an intended experience. Only the build reveals the actual one, and in this shape that's also the last step.

The length of that loop quietly sets a ceiling. If it takes two weeks to feel a decision, you get one honest revision every two weeks.

02. The panel that looked right

We build Humanely, a company operating system that brings people, legal entities, offices, assets, ownership, compliance and company knowledge into one place, with an assistant that can work across that information. The team is small, so design and engineering sit close together. When something in the process isn't working, we tend to find out quickly.

The moment I keep coming back to is the assistant panel. The frames were fine. All the states drawn, empty and filled versions ready, reviewed and agreed. I remember being fairly confident about that one. Then I opened the built version, asked it a real question, and sat there while nothing happened for just long enough to wonder whether it had heard me. Then the answer arrived: fast, fluent, a little too pleased with itself. And my eyes kept getting dragged to the newest line at the bottom while I was still trying to read the top.

None of that was in the file. It couldn't have been. The layout wasn't wrong. The frames I'd drawn were all present in the build, in order. What was wrong lived between them. The length of the pause, the pace of the text, where attention went. Together they made the assistant feel less trustworthy than it actually was. The thread's three states look unremarkable side by side, which is the point.

fig-02-assistant-states-light.pngFIG. 02. Our assistant thread pattern, on its own demo data. All three frames were designed and signed off, and they look fine here. The problem we shipped lives in the middle one. Not how it looks, but how long it lasts and where your eyes go while it does.

The review had worked exactly as designed and still missed it. We had checked everything a review of frames can check.

03. Design has a time dimension

A screen is a state. An interaction is a sequence. When you design in frames, you design the states and quietly hope the sequence takes care of itself. For a button, it mostly does. For an assistant, the sequence is the product.

fig-03-time-dimension-light.pngFIG. 03. The states were the easy part. The pauses, the pace, and the ways out are where the interaction was won or lost. None of them fit in a frame.

This matters more for AI features than most, because you can't fully specify a response in advance. Its timing, its length and its quality all vary. The design has to hold up across all of that: what the interface does while it waits, how it admits it isn't sure, how a wrong answer gets corrected. We had been filing those under edge cases. They're closer to the main case. If something behaves over time, the spec has to say something about the time.

04. The world didn't exist yet

There was a second problem underneath, and it took us longer to see because it didn't look like a problem. It looked like tidy screens.

For a long time we designed and tested against placeholder data. A handful of fictional employees, one office, clean records. Everything fit. Every table looked composed. And the product told us almost nothing. A panel answering questions about three fictional employees behaves very differently from one answering for a company with offices in four countries and a compliance history.

What we slowly understood was that we weren't just designing an interface. We were designing an interface for a world, and the world didn't exist yet. A company isn't employee one, two and three. It's people, offices, legal entities, ownership, obligations, relationships. And, just as importantly, missing information, conflicting information, and things that changed three years ago for reasons nobody wrote down. Our placeholder company was hiding the product from us.

The same lesson kept arriving from smaller directions. Names of very different lengths broke compositions that looked settled. A simple-sounding question like "who owns what?" turned out to span share registers, option grants and funding rounds, while our placeholder world had a founder holding a round number.

You don't discover the real interface until the interface has to deal with something real. We eventually realised we had to give the product a company before we could really understand the product. And when we seeded one, we built it as a history rather than a roster. A director who resigned last year stays in the register with her cessation date. One person holds an employment and a directorship at the same time. Switching legal entities changes who the officers are. Rows a clean snapshot could never produce, and nearly every one changed a screen. None of this is specific to our category. The same thing happens anywhere a product represents a messy real system: customers with several accounts, patients with several records, projects with several owners.

05. We started building earlier

The fix for both problems was the same. Get to something real, sooner. We started using Claude Code, an AI coding tool that works in the codebase from written instructions, to put rough working versions in front of ourselves while the design was still a question.

It didn't make us better designers. What it changed was the distance between I wonder if this works and I can try it. When a working draft costs an afternoon instead of a week, you stop saving code for decisions you've already made and start using it to make them. Figma didn't go away. It moved earlier, to the questions it's best at.

It didn't simply make us faster, either. Some weeks we threw away more work than we shipped. Some problems took longer, because we finally had evidence they deserved it. What got cheaper wasn't production. It was learning. Finding out an idea was wrong before spending a week making it beautiful.

The question we started asking was simple: what are we actually trying to find out?

fig-04-medium-table-light.pngFIG. 04. The mistake isn't using the wrong tool once. It's reaching for the same tool for every question.

06. We kept having the same conversations

Working this way surfaced a new problem. It became easy to produce something plausible, and harder to keep everything feeling like the same product. At one point we put two features side by side, built about a week apart. Both worked. Both were defensible. They disagreed about spacing, about how a status should look, about what a table does while it loads. Nobody had decided any of that twice on purpose. It had just been decided twice.

The signal was repetition. We kept explaining the same rules to each other, and then, noticeably, to Claude. This spacing. This is how a status is shown. This is what an empty list says. A decision that keeps getting made needs a home.

That's what our design system actually became: the memory of decisions the team doesn't want to make again. Not a component library, and not documentation. A place where a settled decision goes to stop being re-decided. Some are small and absolute. A status is always an icon and a word, never colour alone, so it survives colour-blindness and bad projectors. Some are structural. We stopped designing each table as a one-off, and the same collection pattern now carries its loading, empty and populated states everywhere records appear.

And one is a rule about the system itself. Nothing becomes shared on its first use. A pattern earns its place on its second use. The first time might be a special case. The second time is a decision. We keep the reasons next to the rules, in one running log, because a pattern without its why gets re-litigated the moment it's inconvenient. Since all of it lives in code, it's also context an AI tool can read. We explain the rules once instead of every time.

fig-05-encode-and-states-light.pngFIG. 05. Our collection pattern in its design-system home, on fictional demo data. The two empty states used to be one design. Real data split them, and now they carry different words and different buttons: "clear filters" versus "create the first one." The failure this prevents is a typo telling someone the collection is empty, with a create-your-first button sitting on top of two hundred existing records.

07. QA changed too

Design QA used to ask: does this match the design? It's an easy question to answer, which is its weakness. It checks the one thing a side-by-side comparison can see, and stays quiet about everything the file never described.

The question we ask now is whether it behaves like the experience we intended. Does the interaction feel right, or slightly panicky? Does the layout survive real content? What happens when something fails? Does the keyboard still work? Some of the worst problems we've caught this way were states that were technically covered and emotionally wrong. An error message that was accurate and felt like being told off. A pixel comparison would have passed it.

It's slower per review, but the outcome is more often a change to the system than another ticket.

08. The loop we use now

This is roughly how it looks today. It isn't a methodology. It's just the order in which we've found it cheapest to stop being wrong.

fig-06-the-loop-light.pngFIG. 06. The loop as it runs today. Encode is the step we found easiest to skip, and the one that compounds. Without it, every feature restarts the same argument.

Encode means more than "add it to the design system." The rule we try to hold is that if we learn something once, the next feature shouldn't have to learn it again. A recent example. An editable card had Edit in its header but Save and Cancel below the card, so the moment you started editing, the commit point moved. In the same card, a value the system computes for you, one you can't edit, was bare text next to bordered inputs, so it read like something had failed to load. Both became rules rather than one-off fixes: the commit point doesn't move (Save replaces Edit, in the same spot), and a locked field is still a field (same shape as its neighbours, a small lock and a reason, never dimmed as if you should look past it). Sometimes the encoded thing is a component, sometimes a token, sometimes one line in the decision log. What matters is that the lesson stops living in someone's memory of a review.

If you want to try one piece of this, take the last two steps. Change one review a week from does this match the design? to use it for five minutes with real content and tell me where it lets you down. Then put the answer where the next feature inherits it. That needs no new tooling, no AI, and no designers who write production code.

09. Where this goes wrong

We've made each of these mistakes, most of them more than once.

  • Building early without deciding what you're testing. A working version answers whatever question you asked it. Ask nothing and you get a plausible artefact and no information.

  • Seeding data that's still tidy. A seed built as a roster teaches you exactly what placeholder data taught you. Build it as a history: resignations, overlapping roles, records that changed for reasons nobody wrote down. Otherwise it keeps hiding the product from you.

  • Encoding a pattern on its first use. The first time is often a special case. Promote on the second use, or the system fills up with rules that were never really decisions.

  • Encoding the rule without the reason. A pattern with no why attached gets re-litigated the first time it's inconvenient, and you have the same argument again with worse notes.

  • Letting QA drift back to matching. Does this match the design? is the easier question, and it reasserts itself unless the review explicitly asks how the thing behaves over time.

10. The part we haven't solved

Working this close to the product has a cost we're still paying attention to. You can get very efficient at validating the ideas you already know how to have. The older, reference-heavy way of working was slower, but it kept dragging in patterns from outside our own product: other tools, other categories, other people's answers to problems we hadn't hit yet. A build loop doesn't do that. It answers the question you asked, and nothing else.

So we still scout, and we still pull apart other products. What's changed is the role that material plays. Exploration generates the possibilities, reality filters them. Inspiration is a starting point, not evidence. An idea from elsewhere has to survive our data, our states and our users before it earns a place. How much outside looking is enough, we're still working out by feel.

What it was actually for

We didn't get better because a tool wrote more code. We got better when the assistant panel could feel wrong on day two instead of week three. When the placeholder company stopped hiding the product from us. And when the things reality taught us stopped evaporating after the review that found them. The two empty states. The commit point that shouldn't move.

That's the loop. Shorten the distance between an idea and reality, then make sure what reality teaches you doesn't get lost on the way back. Every loop should leave the next one smarter. We're still refining ours.

Field notes from Reveriext, on how we build products across design, product and engineering.


Reading that shaped this

  1. Figma Last: a faster, smarter way to build together, Cogent

  2. Figma Never: code is the new canvas, Cogent

  3. Monolayer, Will Pan, on turning design work into evidence

  4. lhom.co.uk, Luiz Ottino, on design and code as one craft

A note on the screenshots: Figures 02 and 05 are captured from our design system's component workshop, running its own fictional demo data. No company, customer or personal information appears in any frame. They show the shared patterns as they exist in the system, deliberately where we review states rather than inside any one feature.

19

Building something?

reLabs takes ideas to products through co-builds, discovery sprints, and incubation.

Working on something like this?

Most engagements start with a single conversation. Tell us what you're building and we'll tell you what we've shipped.