Removing Implementation Assumptions
Requirements arrive with implementation baked in: "the cart is stored in the session", "orders are a table", "search hits the database". Strip each implementation word and see what the sentence still requires — often less, sometimes something different.
The situation, the reflex, and why it stalls
Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.
A requirement seems to force a design. How do you tell which parts of it are the requirement and which are someone's implementation, quietly included?
The spec for the cart says "the cart is stored in the user's session and cleared on logout". You are about to build it that way and you notice that guest checkout — decided last week — has no session to store it in.
Build what the spec says and raise the guest case as a bug later. The spec is the spec; the person who wrote it knows the product; deviating feels presumptuous.
The cart is built on the session, guest checkout is built on a workaround, and the two carts diverge. "Merge the guest cart on login" becomes a feature, then a source of bugs, because the implementation assumption was never questioned.
- The cart is built on the session, guest checkout is built on a workaround, and the two carts diverge. "Merge the guest cart on login" becomes a feature, then a source of bugs, because the implementation assumption was never questioned.
- Every sentence in the spec is treated as a requirement, so the design space is the intersection of everyone's half-remembered implementations. It contains one design, and it is usually the one from the last project.
- Requirements that were actually there — a cart survives a refresh; adding twice yields quantity two — are not separated from the implementation words, so when the implementation changes, nobody knows which properties must survive.
- The spec writer, asked later, says "I just meant it should still be there when they come back". The word "session" was a guess about how, mistaken for a what.
The move
Precisely enough to apply it to a problem you have never seen — not a slogan.
- Read the requirement and underline every word that names a mechanism rather than a property: session, table, cookie, cache, endpoint, database, synchronous, JSON. Each one is an implementation assumption unless someone can say why the property requires it.
- For each underlined word, ask what property it was standing in for. "Stored in the session" was standing in for "the cart is still there after a refresh and, for a logged-in user, after coming back tomorrow". That property is the requirement; the session was one way to get it.
- Rewrite the requirement with only properties. The rewrite is usually shorter, and it usually admits more designs — including the one that handles the case the original could not. "A cart is associated with a visitor; it survives refresh; a logged-in user's cart survives across devices; logout does not delete it" admits a guest cart keyed on a cookie and merged on login.
- Then choose an implementation, and write it separately, labelled as such. The requirement and the implementation now live in different sentences, so when one changes the other can be checked against it (Goal vs Implementation).
The cart sentence, before and after
The spec sentence with mechanism words underlined, and the rewrite with properties only. The rewrite is longer here, which is unusual, because "cleared on logout" turned out to hide a privacy property that the original had compressed to nothing.
The cart is stored in the user's [session] and [cleared on logout]. — One design; no guest cart; the logout rule's purpose unknown.
A cart belongs to one visitor and survives a refresh. A logged-in user's cart is available on their other devices. After logout, the cart is not visible to the next visitor on that device. — Implementation, separately: guest cart keyed on a cookie, persisted server-side; merged into the account cart on login; the cookie is cleared on logout.
Each property can be tested independently and each admits several implementations. The guest case falls out of "belongs to one visitor" instead of being a workaround, and the logout behaviour is now a privacy property that a different implementation would still have to satisfy.
Stripping as a decomposition
The rewrite decomposes naturally into properties, and each property is a leaf with a test. This is the same tree that A Slice Is Testable would want; the mechanism words were hiding it.
- └Belongs to one visitortestable Two visitors on two browsers add different items; each sees only their own.
- └Survives refreshtestable Add an item, reload the page; the item is still there.
- └Follows a logged-in user across devicestestable Add on one device while logged in; log in on another; the item is there.
- └Not visible after logout to the next visitortestable Add, log out, open the store on the same browser; the cart is empty.
- └Guest cart merges on login— follows from the first and third togethertestable Add as a guest, log in to an account with an existing cart; both sets of items are present, quantities summed.
The original sentence had one test — "is it in the session?" — which tests the implementation. Five properties, five tests, any implementation.
Which mechanism words are constraints
Some mechanism words stay. The decision is how to tell — and it is answered by asking who requires it and what would break if it changed, not by how strongly it is phrased.
This word names a mechanism. What is it?
when Nobody outside the team requires it, and the property it stands in for can be met another way. "Session", "table", "synchronous".
cost Strip it; write the property; choose the implementation separately.
when A contract, a law, an existing integration or an operational reality requires it. "Through the payment provider"; "on the existing database"; "no persisted carts, per legal".
cost Keep it, but move it to the constraints list with its source, so the next reader knows it is not a preference (Constraints).
when The mechanism word is being used as shorthand for a behaviour — "cleared on logout" for a privacy property.
cost Rewrite as the behaviour; the mechanism may or may not survive the rewrite.
How to do it
Most important first.
- Underline mechanism words in the spec. If a sentence has none, it is a requirement; if it is all mechanism, it is a design masquerading as one.
- For each mechanism word, write "standing in for: ___" and fill it with a property someone could test.
- Rewrite the sentence with properties only. Check it against the examples the product owner gives — if the rewrite would permit something they would reject, a property is missing.
- Ask the writer what they meant, showing both versions. Most of the time they meant the property; occasionally the mechanism was a real constraint — "it must be in the session because legal says we cannot persist carts" — and now that is written as a constraint (Budget and Legal Constraints).
- Keep the implementation sentence next to the requirement, labelled, so a future reader does not fuse them again.
Worked on a concrete problem
The move has to produce something. This is what it produced.
- "The cart is stored in the user's session and cleared on logout." Mechanism words: session, cleared on logout. Standing in for: survives refresh; is per-visitor; and — asked — "cleared on logout" was standing in for "someone else on the same computer should not see my cart", a privacy property. Rewrite: a cart belongs to one visitor; it survives refresh; a logged-in user's cart is available on their other devices; after logout the cart is not visible to the next visitor on that device. Now the guest cart, the merge on login and the logout behaviour all follow from properties, and the session is one candidate for the guest case.
- "Orders are stored in the orders table with a status column." Mechanism words: table, column. Standing in for: an order persists; it has a lifecycle whose current state can be read. Rewrite: an order, once created, is never lost; its state is one of a known set and every transition is recorded. The rewrite adds "every transition is recorded", which the column could not do — and which the refund investigation last month needed (The Order Lifecycle, Built).
- "Product search queries the database by name." Mechanism words: queries the database. Standing in for: search returns products whose name matches, within tolerance, on the current catalog. The rewrite keeps the database as the obvious implementation and stops it from being a requirement — so when the catalog outgrows it, the requirement is unchanged and only the implementation sentence is edited.
How you know it worked
What now exists that did not before, and what question you can now ask.
- The requirement contains no mechanism words, and every design you can think of can be checked against it.
- The case that the original could not handle — guest checkout — is handled by the rewritten requirement without a special clause.
- The spec writer, shown the rewrite, says "yes, that is what I meant" — or names a real constraint, which is now written as one.
- Requirement and implementation are two sentences with two labels, and a change to one can be checked against the other.
The questions you can now ask
The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.
- ?Which words in this requirement name a mechanism, and what property was each standing in for?
- ?If I remove the mechanism words, what does the sentence still require — and what designs does it now admit?
- ?Does the rewritten requirement handle the case the original could not?
- ?Is any mechanism word a genuine constraint — and who says so?
What can go wrong
- Stripping words that were requirements. "Payments go through the provider" has a mechanism word and is a real constraint — the contract says so. The move asks what the word stands in for; sometimes the answer is "itself, and here is why".
- Rewriting into abstractions so general they admit designs the product owner would reject. "The cart is associated with a visitor" admits a cart that vanishes after ten minutes; the examples the owner gives are the check.
- Doing the rewrite and then building the original design anyway, because it was already in your head. The value is in the design space the rewrite opens; look at it before choosing.
- Applying it to every sentence in a large spec. Most sentences are fine; the move is for the ones that seem to force a design, and for the ones near a case that does not fit.
- Rewriting a spec someone else wrote costs a conversation, and if they meant the mechanism, the conversation was the whole cost — but it was also how you found out.
- A requirement with only properties is harder to estimate than one with a design in it. The design was doing work for the estimator; now the estimate needs the implementation sentence too.
- The wider design space is a cost as well as a benefit: more options to compare, and a temptation to compare them for too long (Deciding Under Uncertainty).
- "Specs should never mention technology." They can, as constraints, labelled as such. The failure is a mechanism that is not a constraint, written as if it were a requirement.
- "This is the same as the why ladder." The ladder climbs a claim to its requirement; this move strips a requirement of the claims hidden inside it. Same direction, different starting point.
- "The spec writer made a mistake." They compressed. Experienced people describe requirements by naming the implementation they have in mind, because it is shorter; the move decompresses it and checks.
Where this applies
Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.
- GENERALEvery requirement written by a person who has built something before contains their implementation. The move is domain-independent; only the mechanism words change.
- STAGE-SPECIFICGreenfield: strip freely, the design space is open. Existing system: many mechanism words are real constraints because the system already works that way, and the move becomes distinguishing "must stay because it is load-bearing" from "stays because nobody asked".
- ILLUSTRATIVEThe cart spec, the refund investigation and the ten-minute cart are invented to show the shape of the rewrite.
Where the depth lives
This domain asks the question and hands the answer off by name.