Skip to content
Page 4 of 7

The Ultimate Test

From Verified to Live

You've built features, verified them against acceptance criteria, and now have automated tests that check themselves. There's one step left: put it in front of real users.

Think back to the Explore step you started with: understanding who you're building for and investigating their workflow. Hopefully you were able to use your AI assistant to research the domain, find patterns in how your users work, and point you in the right direction. But from that very first moment, you started making decisions with incomplete information. You made your best guesses about what your users need, how they'd interact with your application, and what would make their work easier. Then you encoded those guesses into user stories, acceptance criteria, and features.

Your tests verify that the code works as specified. But they can't tell you whether the specification itself was right: whether the features you built actually change and improve your end users' lives the way you intended.

Does the sanctions screening actually help the analyst spot the vessels that matter? Does the vessel detail view surface the right information for a triage decision? Is the traffic display organized the way someone on a 12-hour watch shift would want to scan it?

You won't know until real people use it.

Assumptions

Every decision you made while building is an assumption. Maybe you color-coded items to signal their status: red for high priority, green for normal. But does your user know what red means in your application? Does it mean "urgent," "overdue," or "error"? Maybe you designed a detail panel that opens when someone clicks an item. But will users know the item is clickable? Will they expect to click, or will they expect the information to already be visible? Maybe you added a legend to explain your visual system. But will users notice it, and will the labels make sense to someone who thinks about this domain differently than you do?

These are where assumptions creep in. Unless you are the one and only end user of a piece of software, whatever you build will need to be used by someone else. Those people have different habits, different levels of experience, different expectations for how software should work. Your understanding of the problem is one perspective, not the complete picture. You're working from data and research you could find, and if you're lucky, you got to talk to real users. Every feature you built carries assumptions about how people will understand it, find it, and use it.

Assumptions are not a problem. They're a necessity. You have to make assumptions to move quickly. If you needed to validate every small decision before writing the next line of code, you would never ship anything. That's what stalls out a lot of large programs: they get so focused on sourcing perfect requirements that they never actually build. Assumptions let you move.

But with that speed comes responsibility. Not all assumptions carry the same risk. When you think about an assumption you've made, consider two questions:

  1. How much evidence supports it? Was it a wild guess, a coin flip, or something backed by research and domain knowledge?
  2. What happens if you're wrong? Is it a minor inconvenience (the user's workflow takes a few extra seconds), or is it a serious problem (they can't read critical information during a time-sensitive decision)?

An assumption with weak evidence and high consequences is the kind that keeps you up at night. An assumption with strong evidence and low consequences is probably fine. Most of yours fall somewhere in between, and the ones that matter most are the ones you should validate first.

The only true way to validate assumptions is to put the software in front of real users and watch them use it. That's why deployment matters so much. The longer you wait before shipping, the more assumptions stack up. You start building assumptions on top of assumptions, and the whole thing can collapse if one of your foundational guesses turns out to be wrong. You reduce that risk by shipping early, shipping often, and watching what happens. Put the software in users' hands. See which assumptions hold and which ones don't. Take what you learn and iterate: if something's confusing, redesign it. If something doesn't fit the workflow, figure out how to fit it better. Every round of real-world feedback makes your next set of assumptions more informed.

Surface Your Assumptions

Team Discussion | ~5 minutes total

You've been building for several challenges now. Time to name what you've been assuming.

Step 1: Generate. Each team member picks one feature in your application and names one assumption baked into it. Think about how users will find it, understand it, or use it. Write it down (one sentence).

Step 2: Evaluate. Go around the team and share. For each assumption, discuss:

  • Evidence: How much do we actually know? Did we research this, or did we guess?
  • Risk: What happens if we're wrong? Is it a minor annoyance or a serious problem?

Step 3: Prioritize. As a team, pick the one assumption that has the weakest evidence and the highest risk. That's the one you'd want to validate first if you could put this in front of real users.

You don't need to fix anything right now. The goal is to practice noticing assumptions, because the first step to validating them is knowing they exist.

The Full Pipeline

Here's what the complete workflow looks like, from idea to live application:

  1. Explore: understand who you're building for and what they need
  2. Plan: write user stories with acceptance criteria (your delegation contract)
  3. Implement: hand the story to AI and let it build
  4. Verify: automated tests pass + visual verification confirms the experience
  5. Ship: deploy to a live URL

The first four steps are the Explore → Plan → Implement → Verify workflow from Lesson 1, with Lesson 3's automated tests now handling the Verify step. Deployment is the natural conclusion: once tests confirm the work is verified, ship it.

Tests gate deployment. If your tests pass, you have evidence that the application works as specified. If they fail, something needs to be fixed before it goes live. This isn't about being cautious. It's about being confident. You ship because the tests give you reason to.

The ideal: one command that runs everything, all your quality checks, tests, and the build. A single signal: pass or fail, no partial credit. When that command passes, you're clear to ship. When it fails, you fix before you ship. It doesn't matter who wrote the code: you, AI, or a teammate. The gate is the same.

But notice that the pipeline isn't a straight line. It's a loop. Shipping connects back to Explore. Real users generate real feedback: they use features you didn't expect, ignore features you thought were essential, and ask for things you didn't anticipate. That feedback is how you validate the assumptions you surfaced in the activity above. It becomes the most valuable input to your next round of Explore. You built what you thought users needed. Now you find out if you were right, and what to build next.

Key Insight

Every product is built on assumptions about what users need. Your tests verify that the code works as specified, but they can't verify that the specification itself was right. The assumptions with the weakest evidence and the highest consequences are the ones that matter most, and the only way to validate them is to put the software in front of real users. That's why deployment isn't the finish line; it's where the learning starts. The pipeline loops: Ship connects back to Explore, and what you learn from real users drives what you build next.