Lesson 4.1: Prototype first, then harden
Build a rough working version fast so the customer can react, then make it safe. Learn the three kinds of prototype, a hardening checklist and when to switch.
By the end of this lesson you will be able to build a first working version of a customer's solution quickly, tell the customer honestly what it is and is not, and turn it into something safe to run every day. You will learn the difference between a throwaway prototype, a thin end-to-end slice and an evolving prototype, a rule for keeping a list of shortcuts, a hardening checklist and a way to decide when to switch from one to the other. You will see three real-style projects, one of which goes wrong, and use a simulator to compare shipping a prototype as it is with hardening it first. This lesson opens Module 4, on building in the field. It builds on Module 3, where you found the data, reached it, checked it and learned the rules. Now you start to make something. You need to be able to read a little code, but the ideas apply to any kind of build.
In Lesson 1.1 you met the idea that people react better to something real than to a description. That idea is the heart of this lesson. A customer who is asked what they want will give you an answer that is partly wrong. A customer who is shown a rough working version will tell you exactly what is wrong with it, in detail, in the first five minutes. The first conversation produces opinions. The second produces requirements. This is why forward deployed engineers build early.
The idea comes with a danger that every experienced engineer has met. A rough version that works well enough to impress somebody tends to be put into use, and a rough version in use tends to break at the worst moment. The skill of the role is to get the benefit of early building without paying that price: to move fast at the start and deliberately slow down before anything depends on your work.
Why build early
Three reasons make early building worth the risk.
It finds the real requirements. Customers often cannot say what they want until they see something. A screen, a message or a report makes the abstract concrete, and the corrections that follow are the most reliable guide to what matters.
It builds trust. A customer who sees progress in the first week believes the project is real. Weeks of planning with nothing to show make the same customer anxious.
It finds the technical surprises. Many problems show up only when you connect real data to real code: a field that is always blank, a system that is slower than the documentation says. You want to meet these in week two, not week ten.
The cost is that early work is rough. The answer is to be clear about what the early work is for, and to keep it separate from the work that will be relied upon.
Three kinds of early work
People use the word prototype loosely, and the confusion causes real trouble. It helps to separate three kinds, because each should be treated differently.
The throwaway prototype. It is built to answer a question and then discarded. Its job is to learn: can the data be joined this way, does this screen make sense to the user, is this model accurate enough to be worth pursuing? The code can be messy, because it is not meant to last. Dave Thomas, one of the authors of The Pragmatic Programmer, describes prototypes in just this way, as things that are not designed to be long-lasting code.
The thin slice, or tracer. It is a small but complete path through the whole system, from input to output, built as real code that will stay. The same book calls it tracer code, and describes it as lean but complete, forming the skeleton of the final system. Another name for the same idea is a walking skeleton, a term coined by Alistair Cockburn: a tiny implementation that performs one small end-to-end function and is tested from the start. It differs from a prototype because it is meant to be kept and built upon.
The evolving prototype. It starts rough and is grown, through regular feedback from the people who will use it, into the finished product. It can work if the team is disciplined about improving the foundations as it goes. It is the riskiest of the three, because the line between "rough" and "finished" is easy to blur.
The practical rule is simple. A prototype is for learning, and a thin slice is for delivering something you intend to keep. Before you write a line, decide which one you are building, and tell the customer.
The danger: the prototype that ships
The common failure has a name, and it is worth recognising early. You build a quick prototype to learn something. It works. The sponsor sees it, loves it and asks whether it can be used next week. The team is under pressure, and the answer drifts from "it is only a prototype" to "well, it works". Soon it is in production, with a handful of shortcuts nobody has written down, handling real data without the checks, the logging or the security it needs.
Programmers have written about this for years. Jeff Atwood's essay "The Prototype Pitfall", which draws on the writer Robert Glass, warns that prototypes tend to leak their shortcuts and weak habits into the final product, and that they often never get retired. His remedy is discipline: design a prototype to be thrown away, and if you cannot bring yourself to discard it, build the thin, complete skeleton described above instead. He even suggests building prototypes in a different language, so that it is harder to reuse the code casually. The lesson is not to avoid prototypes. It is to make the unfinished state visible, so that nobody mistakes a demonstration for a product.
Several habits help.
Label it. Put "prototype" on screens, reports and messages, and say it in the room. If it is going to a pilot, call it a pilot.
Keep a list of shortcuts. Every time you take a shortcut, write it down: "no retry logic", "reads from a spreadsheet", "no tests", "one hard-coded account". This list is your honest account of what is missing, and it becomes the plan for hardening.
Use real data from the start. A prototype on clean sample data teaches little. Real data exposes the problems early, and you can still be clear that the code is rough.
Time-box it. Decide how long the prototype may take, for example three days, and stop at the limit. A prototype that grows without limit is turning into a product by accident.
Say what it proves. Write one sentence about what the prototype is meant to show, and one about what it does not.
Predict first: your three-day prototype impresses the sponsor, who says: "This is exactly what we need. Can the whole collections team use it on Monday?" You know it has no error handling, no tests and one hard-coded account. What do you say? Decide before reading on.
The honest, constructive answer is something like: "I am glad it is useful. Today it is a prototype. It works on the cases we tried, and it has no protection against the cases we have not. I can make it safe to use with the team in about two weeks, and I would like to use the shortcuts list to plan that. In the meantime, I can run it myself for a few accounts and show you the results." This takes the pressure seriously and offers a path, a small controlled use, in place of a flat refusal. It also puts a price on the difference between a demonstration and a tool, which is the information the sponsor needs to decide. Shipping silently, with the shortcuts unspoken, is the one thing you must not do.
Build a thin slice first
When you start, resist the urge to build the parts you find most interesting. Build a thin slice: the simplest possible version that goes all the way from input to output, for one case.
For the lender's reminder pilot, that means: read one account from the nightly file, decide which group it belongs to, produce one message in the borrower's language, and show it on a screen. It handles one account, uses a fixed rule and sends nothing. But it touches every layer: the data, the logic, the output. The surprises that were going to appear anyway appear on day two, while the work is still small.
Then widen it, one step at a time. More accounts. The real rule. The second language. The real sending. Each step is small enough to finish, test and show. At no point do you have a pile of half-built parts that do not yet fit together. This approach, sometimes called working in vertical slices, also gives you something to show every few days, which Lesson 1.3's advice to show something small every few days already said was valuable.
The shortcuts list
A shortcuts list is the single most useful artefact of a prototype. Keep it in a plain file next to the code, and add to it as you go. Each entry has three parts: what the shortcut is, why you took it and what it would take to remove it. A few examples:
Shortcut · Why · To remove itReads a local copy of the nightly file · The real transfer is not approved yet · Connect to the file server, handle late and repeated files
No retry when the message service fails · Not needed for the demo · Add backoff, a queue and a catch-up job
Language defaults to English when missing · Half the records are blank · Agree a rule with the steward, flag the rows
One hard-coded test account · Quick to build · Read accounts from the file, add checks
No tests · Speed · Write tests for the grouping rule and the message builder
The list does three things. It keeps you honest, because writing "no retry logic" makes you aware of it. It helps the customer, who can see exactly what is missing and what it will cost to fill. And it saves you when the prototype is asked to go live: you do not have to remember what you skipped, because it is written down.
Hardening: from works to dependable
Hardening is the work of turning something that works on the cases you tried into something that keeps working on all the cases it will meet. It is not glamorous, and it is where most of the effort goes. A useful checklist has eight parts.
1. Correctness on the unusual cases. Blank values, duplicates, odd formats, huge or tiny amounts, records that arrive twice. Lesson 3.3's checks live here.
2. Error handling. What happens when a service is down, a file is late or a login expires? Lesson 3.2's retries, backoff and catch-up jobs belong here. The program should fail clearly and safely, never silently.
3. Security and access. Secrets in protected storage, least access, named accounts, masked data. Lesson 3.4 covers this.
4. Tests. Automatic checks that the main rules still work after every change, especially the parts that decide what a customer sees or is charged.
5. Logging and monitoring. A record of what the program did, and alerts when something goes wrong or when expected work does not happen. A program that fails quietly is the most dangerous kind.
6. Performance. Does it still work with a hundred times the data, or in the busiest hour? Test with realistic volumes.
7. Deployment and rollback. A repeatable way to put it into the customer's environment, and a quick way to go back to the last good version. Module 5 covers this in depth.
8. Documentation and handover. What it does, how to run it, what to do when it fails, and who owns it. A system that only its builder understands is a risk to the customer.
The picture explains the sponsor's mistake in the example above. The demo showed the first slice of the pie, about a fifth, and it looked complete because the part that people see is a small part of the work. When the sponsor says "it is exactly what we need", they are right about the fifth they saw and unaware of the rest.
The pie above gives a way to size the hardening. If the demo showed about a fifth of the work, then the days you spent on it tell you roughly how many are left. Try your own numbers.
At the defaults, a three-day prototype that represents a fifth of the work means about fifteen days in all and twelve still to do, about two and a half weeks for one engineer. If the prototype is only a tenth of the work, the remainder is twenty-seven days.
When to harden
Hardening costs time and, if done too early, wastes it. A prototype may be thrown away after the customer reacts, in which case any hardening was a waste. The question is when to switch. A good rule is to harden when three things are true.
The customer has committed. A pilot is approved, a metric is agreed and the sponsor wants to go on.
The direction is stable. The last two demos produced changes in details, not in what the thing is for.
Real users are about to depend on it. Anything that touches real money, real messages or real decisions needs to be hardened before it does so.
Until then, stay light. After that, stop adding features and spend a defined period, often a third to a half of the project, on the checklist. A good plan treats hardening as a visible phase, with a date and a list, not as something that happens "in the gaps".
Worked example 1: the reminder prototype
On day three of the lender's pilot, the engineer has a prototype that reads a sample file, sorts accounts into two groups and shows the proposed message for each of ten accounts on a screen. It uses real data, with names masked. It does not send anything.
The engineer shows it to the head of collections, who reacts at once: "Move accounts that paid last month to the easy group. And the second group needs a call, not a message." Those two corrections are worth more than a week of requirements meetings, and they came on day three because there was something to look at. The engineer updates the shortcuts list with five entries and the plan with a hardening phase in weeks four and five.
The key choices were small. The engineer labelled the screen "prototype", used real data, kept a list and agreed the hardening time before the first demo. When the head of collections asked, in the same meeting, whether the team could use it the following week, the answer was the one described above: not yet, here is why, and here is when.
Worked example 2: the bed screen skeleton
For the hospital group's bed screen, the engineer starts with a thin slice instead of a prototype, because the screen will certainly be needed. The slice reads the bed status for one ward in one hospital, from a nightly file, stores it and shows it as a single row on a web page. It is ugly and complete.
Each week it grows: more wards, a second hospital, a colour for each status, the manual-register exception that Lesson 3.1 found. Because the slice is real code with tests from the start, every addition is built on something solid. There is a screen to show the chief operating officer after three days and a reliable one after six weeks, and no point at which the engineer had to throw away work.
The trade-off is that a thin slice takes slightly longer to build on day one than a throwaway prototype, because it has to be kept. The saving comes later, when there is no rewrite. Choose the slice when you are confident the thing will be kept, and a throwaway prototype when you are still unsure whether the idea works at all.
Worked example 3: the prototype that shipped
A support assistant prototype, built in four days, drafts replies for customer questions using the company's help pages. It impresses the head of support, who asks for it to be used by the whole team the next week. The engineer, under pressure from the sales team, agrees. The shortcuts list exists but is not shared.
In week three, the assistant starts to give a customer an out-of-date refund rule, because the help pages it reads had been updated in one place and not another, and there was no check or alert. An agent sends the reply without reading it closely. The customer is told something the company does not honour, and the complaint reaches the head of support. The team stops using the tool for a fortnight. The engineer spends the next two weeks doing the hardening that was skipped, under far worse conditions than if it had been planned: no check on the source pages, no review step for refunds, no log of what was drafted from which page.
Nothing in the story is surprising. Every item was on the shortcuts list, and the failure was the one the list predicted. What turned a known gap into an incident was that nobody with authority had seen the list or agreed a plan. The cost of the incident, a lost fortnight and some trust, was larger than the hardening would have been.
Comparing the two paths
You can put rough numbers on the choice between shipping a prototype as it is and hardening it first. Suppose an unhardened prototype in use has some chance each month of a failure that causes an incident. Hardening costs a fixed time up front and leaves a much smaller chance of failure. Over enough months, hardening pays for itself.
The simulator below does the arithmetic. Set the cost of hardening, the monthly chance of an incident with and without hardening, the cost of an incident in team-weeks (including rework and the customer's lost confidence) and the number of months the system will run. It shows the expected cost of each path and how many months it takes for hardening to pay back.
The chances and costs are your own estimates, so treat the result as a way to structure a conversation with the sponsor, not as a forecast. Try three experiments. First, keep the defaults and see how the two paths compare over six months. Second, lower the incident cost to one week, which describes a harmless internal tool, and see that hardening may not be worth it. Third, raise it to ten weeks, which describes a system that touches money or patients, and see how quickly hardening pays back.
At the defaults, shipping as it is costs 9 team-weeks in expected incidents over six months. Hardening costs 5 weeks up front plus about 1.1 weeks of residual risk, 6.1 in all, and it pays back in about 3.8 months. The numbers are made up, and the shape is general: the longer a system runs and the more an incident costs, the sooner hardening wins. For a one-off script that runs for a week, shipping as it is can be right. For anything that will run every night for a year, it almost never is.
Keeping the customer in the loop
All of this works better when the customer understands it. A few habits help.
Say what stage it is at. "This is a prototype. Next is a pilot-ready version, and then production." Use the same three words in every update.
Show the shortcuts list. Sharing it turns a worry into a plan and gives the customer a say in the order.
Price the hardening. Put it in the plan as a visible phase, with a date. A sponsor who sees it will usually protect the time.
Offer a controlled early use. If the customer is eager, propose a small, supervised trial, such as a few accounts you check by hand, as a bridge between a demo and a rollout.
Say no kindly and early. If asked to put an unhardened system in front of many users, say what could go wrong in terms they care about, such as wrong messages or wrong numbers, and what you would need to make it safe.
Common mistakes
Polishing a prototype. If it is to be thrown away, do not spend time on its appearance. Polish makes people believe it is finished.
Letting a prototype ship silently. Keep the shortcuts list, share it and agree a hardening plan before real users depend on it.
Building on fake data. Real data shows the real problems. Mask it if it is sensitive.
No time-box. An unlimited prototype becomes a product by accident.
Building the interesting part first. Build a thin slice that goes end to end, then widen it.
Hardening too early. Wait until the customer is committed and the direction is stable.
Treating hardening as spare time. It is a phase with a date, a list and an owner.
Hiding the shortcuts. The list is your protection and the customer's information.
Key takeaways
A rough working version teaches more in five minutes than a week of requirements meetings, so build early.
There are three kinds of early work: the throwaway prototype for learning, the thin slice for delivering something you keep and the evolving prototype. Decide which one you are building, and tell the customer.
The prototype that ships silently is the classic failure. Label it, keep a shortcuts list and agree hardening before real users depend on it.
Build a thin slice that goes from input to output for one case, then widen it step by step.
Hardening has eight parts: unusual cases, error handling, security, tests, logging and monitoring, performance, deployment and rollback, and documentation and handover.
Harden when the customer has committed, the direction is stable and real users are about to depend on it. The longer it will run and the more an incident costs, the sooner hardening pays back.
Check yourself
1. Name the three kinds of early work and what each is for.
The throwaway prototype is for learning and is discarded. The thin slice is a small end-to-end piece of real code that is kept. The evolving prototype is grown into the product through feedback.
2. The sponsor asks to put your three-day prototype in front of the whole team on Monday. What do you say?
That it is a prototype that works on the cases tried. Offer a hardening plan with a date based on the shortcuts list, and a small supervised use in the meantime. Do not ship it silently.
3. Why keep a list of shortcuts?
It records what is missing, becomes the hardening plan, and protects you and the customer from forgetting what was skipped.
4. Hardening costs 4 team-weeks. An unhardened system has a 20 per cent monthly chance of an incident costing 5 team-weeks, and 2 per cent after hardening. Over 6 months, what is the expected cost of each path?
Shipping as it is: 6 × 0.20 × 5 = 6 weeks. Hardening first: 4 + 6 × 0.02 × 5 = 4.6 weeks.
5. Give two signs that it is time to harden.
The customer has committed to the pilot, the last demos changed only details, or real users are about to depend on it.
Try this
This exercise takes about forty minutes and gives you a prototype and a shortcuts list. Use a small problem you know well, such as a weekly report or a tracker.
1. Write one sentence on what the prototype is meant to show, and one on what it does not.
2. Decide whether you are building a throwaway prototype or a thin slice, and write why.
3. Build the thinnest version that goes from input to output for one case, using real data or a masked copy. Put a time-box of two hours on it. A spreadsheet, a short script or a form is fine.
4. As you go, write each shortcut in a table: what it is, why you took it and what it would take to remove it. Aim for at least five entries.
5. Show it to the person who would use it. Write down their first three reactions in their own words.
6. Go through the eight-part hardening checklist, and write for each one what it would take for your prototype. Estimate the total in days.
7. Use the simulator with your own estimates to decide whether hardening is worth it.
A good result is a working rough version, a shortcuts list, three real reactions and a hardening plan with an estimate. It is the same sequence you would follow with a customer, and having done it once, you will find it easier to resist the pressure to ship a prototype before it is ready.
Sources
[Tracer Bullets and Prototypes](https://www.artima.com/intv/tracer.html), Artima, an interview with Dave Thomas, co-author of The Pragmatic Programmer. Used for the distinction between prototypes, which are throwaway, and tracer code, which is lean but complete and forms the skeleton of the final system. I read search summaries of this page and not the full interview.
[The Prototype Pitfall](https://blog.codinghorror.com/the-prototype-pitfall/), Jeff Atwood, Coding Horror. Used for the points that prototypes leak shortcuts into the product and often never get retired, that a prototype should be designed to be thrown away, and that tracer code is the alternative when it cannot be discarded.
The term "walking skeleton" is credited to Alistair Cockburn in several articles. The description here comes from secondary summaries.
The three projects, the effort split, the shortcuts table and the simulator's figures are the author's illustrations for teaching, not data from real companies.
Tags: Forward Deployed Engineer Prototyping Software delivery Production readiness Beginner