What Can I Ignore for Now?
A frame lists everything the system will need; V1 needs a fraction of it. Deciding what to ignore — and writing down why, and what would bring it back — is how a project gets small enough to start without forgetting what it left out.
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.
The frame is complete and it is too big to build. How do you decide what to leave out of the first version, how do you tell "ignore for now" from "ignore at your peril", and how do you make sure the ignored things come back?
The store's frame has coupons, multiple warehouses, reviews, search, multi-currency, accounts, and refunds on it, all of them wanted. You could build for a quarter before a customer buys anything. You know you should cut, and every cut feels like a promise broken.
Build the easy ones first and defer the rest by not mentioning them. Coupons are a small feature; reviews are a small feature; each one shipped is visible progress, and the hard cuts — refunds, inventory under concurrency — can wait until someone asks.
The easy features are built and the core is not. Reviews exist for products nobody can buy, because checkout — the thing the store is for — was never the easy one.
- The easy features are built and the core is not. Reviews exist for products nobody can buy, because checkout — the thing the store is for — was never the easy one.
- Things are deferred by silence rather than by decision, so nobody knows whether refunds were cut, forgotten, or assumed to be someone else's. The founder assumes they are coming; the engineer assumes they were dropped.
- The wrong things get cut. "We will do inventory properly later" ignores an invariant; "we will do coupons later" ignores a feature. Deferring the first is a bug with a delivery date, and it looks identical to deferring the second.
- Cut things never return. Without a written reason and a trigger, the not-V1 list is a graveyard, and each item is rediscovered as a surprise when a customer asks for it.
The move
Precisely enough to apply it to a problem you have never seen — not a slogan.
- Sort the frame by a different question than "what is easy". Ask, for each item: is it on the core workflow? Is it an invariant? Would leaving it out make the V1 wrong, or just smaller? The items that make V1 wrong when absent cannot be ignored, however hard; the items that make it smaller can, however easy.
- Separate simplify from ignore. Most requirements can be met in a smaller form: one currency instead of many, one warehouse instead of several, filter-by-name instead of search. The requirement is met; its generality is deferred. A few cannot be simplified below a floor — payment correctness, not overselling — and those get built properly or not at all (What Cannot Be Simplified).
- For everything ignored, write three things: what was left out, why it is safe to leave out now, and what would bring it back. "Multi-currency: all customers are in one country; revisit when the first order from abroad arrives." The trigger is what turns a cut into a decision instead of a loss (The Assumption Register).
- Cut in a way that leaves the door open. Ignoring multi-currency is fine; storing prices as bare numbers with no currency column makes the return expensive. The move is to leave the field out of the workflow, not to make its future addition a migration (Reversible vs Irreversible Decisions).
Four kinds of "later"
The decision that does the sorting. The question is not "how hard is it?" but "what happens to V1 if it is absent?" — and the answers fall into four kinds, only two of which can be ignored. The cost column is what the choice costs, which for the first two kinds is the cost of not being allowed to cut.
For an item on the frame, what does leaving it out do to the first version?
when Without it, a customer cannot complete the workflow that makes it a store.
cost Cannot be ignored. It is V1 by definition, however hard.
when Without it, V1 can do something that must never happen — oversell, double-charge, lose a file.
cost Cannot be ignored; can sometimes be enforced by a human at very small scale, and that is a decision to write down, not a default.
when The requirement can be met in a smaller form: one currency, one warehouse, filter instead of search.
cost Simplify to the floor; write the assumption; keep the door open in the data model.
when Without it, V1 is smaller and still right: coupons, reviews, recommendations.
cost Ignore, with a reason and a trigger; check that the goal's observation survives the cut.
The store, with the cuts made
An order of work after the sort. Everything cut is off the list, everything simplified is marked with its floor, and the invariants are early rather than late because they are the hardest and cutting them is not allowed. The alternative order is the MVP-purist one, and it is a real choice for a store with a handful of known first customers.
- 1Catalogue: products listed and viewed; filter by name (search simplified to its floor)
because First customer action; the simplification is written down and a search engine has a trigger.
- 2Cart, keyed by session (accounts simplified to guest-only)
because Guest checkout is the goal; the cart must not be welded to a user id or accounts can never be added cheaply.
- 3Checkout: validate, snapshot prices, create order — one currency, one warehouse, each with a column that leaves the door open
because The core workflow reaches "an order exists"; the simplifications are floors, not omissions.
- 4Payment with exactly-once enforcement and stock checked under concurrency
because The two invariants; hard, early, and not cuttable (Invariants in an Online Store).
- 5Confirmation, and failure messages for each condition that can fail
because The customer must know the outcome; this closes the core workflow.
- 6Nothing else until a trigger fires
because Coupons, reviews, refunds-in-UI and multi-currency each have a written trigger, and building them before it fires is speculation.
A slice that ignores, honestly
The first slice after the cuts. It touches every layer of the core workflow and nothing off it, and its doesNotProve field is the not-V1 list restated: everything the slice leaves out is named so that nobody mistakes a passing slice for a finished store.
- Product pageShows one product with price and stock; adds it to a session cart.
- Checkout APIValidates the cart, snapshots prices into an order, checks stock under a constraint, requests payment with an idempotency key.
- Payment providerTest-mode charge; confirmation received and matched to the order once.
- DatabaseProduct, Cart, Order, OrderItem with snapshot price, Payment with confirmation id; a currency column that is always the same value for now.
- Confirmation pageOrder id and what was bought; on failure, which condition failed.
How to do it
Most important first.
- List every item on the frame. Mark each as: core workflow, invariant, simplifiable, or deferrable. Only the last two can be ignored, and the third only down to a floor.
- For each deferred item, write its return trigger — an event, a number, a customer request — and put the list where it will be seen, not in a closed ticket (What Is Not V1).
- For each simplified item, write the assumption that makes the simplification safe: "one warehouse: stock is a single number per product" — and note that the schema should not make a second warehouse a rewrite.
- Check the cuts against the goal: does V1, with these cuts, still produce the observation the goal named? If the goal was orders from guests and accounts are cut, yes; if search is cut and the catalogue is large, maybe not.
- Revisit the list when a trigger fires, and when the goal changes. A cut made in the first month can be wrong by the third (Growing From the MVP).
Worked on a concrete problem
The move has to produce something. This is what it produced.
- The store's frame, sorted. Core workflow: browse, cart, checkout, pay, confirm. Invariants: never oversell, never double-charge — cannot be ignored, built properly in V1 even though they are hard. Simplifiable: currency (one), warehouse (one), search (filter by name), accounts (guest only). Deferrable: coupons, reviews, refunds through the UI. Each of the last three has a reason and a trigger: refunds are handled manually through the provider's dashboard until the first week with more than a handful; coupons wait for a marketing campaign; reviews wait for enough orders to have any.
- The cut that was wrong. "Inventory under concurrency — later, we have no traffic." It is an invariant, not a feature; cut, it means a V1 that can oversell, which is a V1 that is wrong. It moved back into V1 the moment it was sorted correctly, and it cost a day, not the quarter the reflex feared.
- The file-upload service. Frame: upload, download, share by link, virus scan, resumable upload, quotas, expiry. Core: upload and download. Invariant: a file downloaded is byte-identical to the one uploaded — cannot be ignored. Simplifiable: share-by-link (one permanent link, no expiry). Deferrable: resumable upload (trigger: first failed large upload from a real user), quotas (trigger: storage cost crossing a threshold), virus scan (trigger: opening uploads to people outside the team — and that trigger is a hard one, because it is a security floor, not a feature).
How you know it worked
What now exists that did not before, and what question you can now ask.
- Every item on the frame has been sorted into core, invariant, simplifiable or deferrable, and nothing in the first two categories has been cut.
- Every cut has a written reason and a return trigger, and the list is somewhere it will be read.
- The simplifications have their assumptions written, and the data model does not make undoing them a rewrite.
- V1 still produces the observation the goal named.
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.
- ?For each item: is it on the core workflow, an invariant, simplifiable, or deferrable — and which of those can actually be ignored?
- ?For each cut: why is it safe now, and what event would bring it back?
- ?Does the simplification leave the door open, or does the data model make returning a rewrite?
- ?With these cuts, does V1 still produce the observation the goal named?
What can go wrong
- Invariants are cut because they are hard. "We will do idempotent payments later" is not a scope decision; it is a defect scheduled for production. The sort exists to stop this, and it only works if it is done honestly.
- Nothing is cut because every item has an advocate. A not-V1 list with two entries is a project that will not ship; the sort has to produce cuts, and the goal is what settles the arguments.
- Cuts are made so hard that the door closes. Prices stored without a currency, stock stored as one number with no location, a cart welded to a user id — each makes the deferred item a migration, and the deferral becomes permanent by cost.
- The list is written and never revisited. Triggers that nobody watches are decoration; the list needs an owner and a rhythm.
- A written not-V1 list is a list of things a stakeholder wanted and did not get, with reasons they can argue with. Silence avoided the argument; the list has it now, when it is cheaper.
- Leaving doors open costs a little now — a currency column nobody uses, a location on stock — and every open door is a small piece of speculation that may never pay off.
- Building the invariants properly in V1 is the slowest part of the smallest version, and it delays the first customer. The alternative is a first customer who can be double-charged.
- "Just ship an MVP" means cut everything that is not the demo. Made precise: cut everything not on the core workflow and not an invariant, simplify the rest to a floor, and write down what would bring each cut back. An MVP that cuts an invariant is not minimal; it is broken (MVP vs Bad Prototype).
- "Ignore for now means it is not my problem." It means it is a recorded decision with a trigger. The item is still yours; its time has not come.
- "The easy features are free, so keep them." Every feature in V1 is a feature to maintain, test and explain, and a feature off the core workflow is cost without evidence. Easy is not a reason.
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 frame is larger than its first version, and the four-way sort applies to any of them; what counts as an invariant is domain-specific and is where the honesty of the sort is tested.
- CONTESTEDA strong opposing view — MVP purism — holds that even the invariants should be simplified at first: take payments manually, track stock in a spreadsheet, and let the first customers reveal which invariants matter before any are engineered. On that view, building idempotent payments before a single order exists is speculation like any other, and the honest floor is "a human checks". It is strongest where the first customers are few and known and a human really can check every order.
- ILLUSTRATIVEThe store's feature list, the triggers and the file-upload service are invented to show the sort; the thresholds are for the shape of the argument, not real numbers.
Where the depth lives
This domain asks the question and hands the answer off by name.
- — The What Should I Build First? lab at /thinking/first takes a feature list with dependencies, risk and value and shows the order — and the risky thing to prototype early — for the store after its cuts.