Every Feature Is a Bet You Never Wrote Down

· Roman Miakotin

  • engineering-practice
  • product-thinking
  • founder
  • decision-making
  • hypothesis-driven-development
A dotted trail zigzags erratically across the floor but drifts steadily toward a single dial on the wall, while a small figure crouches to follow its path, a cobalt notebook beside them.

Hypothesis-Driven Development: Be Wrong Locally, Move Right Globally

Software development under uncertainty is not primarily a construction process. It is a search process.

I once spent several weeks building something that seemed obviously useful.

The implementation was good. The reasoning sounded good. The feature solved a real problem — at least according to the story I had in my head while building it.

Then it shipped.

Almost nothing happened.

That part is not unusual. Every engineer eventually builds something nobody needs.

The more interesting failure comes afterward.

Suppose someone asks:

What exactly did you expect to happen?

Not why the feature seemed reasonable.

Not why users should have wanted it.

What observable change did you predict before writing the code?

And what result would have convinced you that your original judgment was wrong?

Very often, there is no good answer.

There was an intuition. There was reasoning. There may even have been a roadmap and a detailed architecture.

But there was no prediction precise enough to fail.

And if nothing can clearly fail, very little can be learned.

That is where Hypothesis-Driven Development begins.


Every feature is a bet

Every engineering decision contains an implicit prediction.

When we build a feature, adopt a technology, introduce a cache, move to microservices, add a recommendation engine, or redesign onboarding, we are effectively saying:

If we do X, we expect Y to happen.

The problem is that teams usually write down X and forget Y.

The backlog says:

Implement recommendation service.

It rarely says:

We believe recommendations will increase the number of products viewed per session by at least 20% within three weeks.

The architecture document says:

Introduce Kafka.

It rarely says:

We believe asynchronous processing is necessary to sustain the expected traffic while preserving acceptable request latency.

Without the second part, implementation becomes disconnected from evidence.

A feature is really a hypothesis with code attached to it.

And an architectural decision is often a hypothesis with an infrastructure bill attached to it.


Write down what would prove you wrong

At its simplest, Hypothesis-Driven Development does not require a new methodology, a Jira workflow, or another planning ceremony.

A useful hypothesis can fit into one sentence:

We believe [change] will produce [outcome], and we will consider that belief supported if [observable signal] reaches [threshold] within [timeframe].

For example:

We believe simplifying registration will increase completed signups by at least 15% within two weeks.

Or:

We believe batching writes will allow this service to sustain 50,000 events per second while keeping p99 latency below 100 ms.

Or:

We believe three public data sources can provide at least 20,000 fresh property listings per week with less than 10% extraction failure.

The specific structure matters less than one property:

the statement must be capable of being wrong.

“Users will like this” is not a useful hypothesis.

“Support requests about setup will fall by 30% within a month” is.

The purpose is not bureaucracy.

It is to force an intuitive belief into a shape reality can contradict.


The real enemy is hindsight

Humans are remarkably good at explaining outcomes after they happen.

If the feature succeeds:

Of course users wanted it.

If it fails:

The timing was wrong.

We need another iteration.

The market is not ready.

We didn’t promote it enough.

Any of those explanations may be true.

The problem is that without a prediction recorded before the result, we cannot distinguish learning from storytelling.

Our brains quietly rewrite yesterday’s uncertainty using today’s information.

A written hypothesis creates a receipt.

It lets us compare:

what we believed

what we predicted

what actually happened

how wrong we were

That last step is more important than it looks.

Because good engineering intuition is not magic.

It is calibration accumulated across hundreds of correctly scored decisions.

If our predictions are never scored, our intuition cannot improve reliably. It can only become more confident.


But one hypothesis is not enough

This is where Hypothesis-Driven Development becomes more interesting than simply writing success metrics for features.

Real software projects rarely contain a single unknown.

Consider building a real-estate valuation product.

Before implementing the platform, we might implicitly assume all of the following:

  • enough market data can be acquired;
  • listings from different sources can be normalized;
  • duplicates can be identified;
  • asking prices contain enough market signal;
  • valuation accuracy can reach an acceptable range;
  • users care about the result;
  • users will pay for it;
  • acquisition and computation costs allow a viable business.

The conventional response is often to begin designing the system:

collectors
→ ingestion pipeline
→ storage
→ deduplication
→ ML
→ API
→ dashboard
→ billing

But notice what happened.

We turned a collection of unknowns into a collection of implementation tasks.

That transformation is dangerous because tasks create momentum.

Once the ingestion pipeline exists, it feels natural to build the storage layer.

Once the storage layer exists, it feels natural to build analytics.

Soon the project has invested months of work before answering the question that could kill the entire idea.

A hypothesis-driven representation looks different:

Can we obtain enough data?

Is the data good enough?

Can we extract a useful signal?

Does that signal solve a real problem?

Will someone pay for it?

Can we deliver it economically?

This is not a feature roadmap.

It is an uncertainty map.

And that changes what the team should optimize.


Optimize for Time to Corrected Belief

Traditional engineering organizations spend enormous effort reducing:

Time to Implementation.

That matters when the destination is known.

Under uncertainty, however, a more important metric comes first:

Time to Evidence.

And before implementation should come:

Time to Corrected Belief.

The development loop becomes:

Belief

Hypothesis

Experiment

Evidence

Corrected Belief

Decision

Only then:

Decision

Implementation

This distinction sounds academic until we look at engineering cost.

Imagine a team considering a new architecture.

Option A requires three months to implement properly.

But a deliberately ugly two-day prototype can tell us whether the fundamental performance assumption is even true.

Those two days may save three months.

The prototype did not create product value directly.

It bought information.

That is often the highest-value thing software can do.


Every experiment should buy information

A useful question before any experiment is:

What decision will change depending on the result?

If the answer is “none,” the experiment is probably unnecessary.

An experiment has a cost:

engineering effort
+ infrastructure
+ operational effort
+ opportunity cost

But it also has a Value of Information.

A rough mental model is:

Value of Information

probability that evidence changes the decision
×
cost of the wrong decision avoided

This leads to a counterintuitive conclusion.

A $10,000 experiment can be cheap if it prevents a $1 million mistake.

A two-day prototype can be expensive if everyone knows they will proceed regardless of the outcome.

The purpose of experimentation is therefore not to “validate ideas.”

That wording already contains bias.

The purpose is to change decisions when reality disagrees with us.


Minimum Viable Experiment

This is also why the traditional MVP is often too large.

Teams say:

Let’s build an MVP.

Then the MVP acquires:

  • authentication;
  • user management;
  • databases;
  • deployment;
  • observability;
  • an admin interface;
  • billing;
  • API versioning.

Three months later, the team has produced a small production system.

But the original question may have been:

Will anyone pay $20 for this result?

That can sometimes be tested with:

landing page
+
form
+
manual workflow
+
LLM
+
payment link

No scalable architecture.

No elaborate backend.

Perhaps no real product at all.

That is not a bad MVP.

It is something better suited to the question:

a Minimum Viable Experiment.

The implementation should be only sophisticated enough to answer the question being asked.


Probe, Prototype, Product

This leads to a useful distinction.

Probe

Lives for hours or days.

Its purpose is to answer one question.

Quality means: we can trust the result.

It does not mean: reusable abstractions, deployment automation, or perfect architecture.

Prototype

Lives for weeks.

Its purpose is to test how several ideas behave together.

Some engineering quality matters, but technical debt may be entirely rational.

Product

Lives for years.

Now maintainability, security, observability, scalability, compatibility, operations, and cost become first-class concerns.

One of the most expensive mistakes in exploratory engineering is applying Product Engineering to a Probe.

The opposite mistake is equally dangerous:

Probe → "it works!" → Production

A safer transition is:

Probe

Evidence

Decision

Production Design

Experimental code proves a belief.

It does not automatically prove its own architecture.


Once teams accept hypothesis-driven development, another failure mode appears.

Endless exploration.

There are always more things to investigate.

A different model.

Another database.

Another customer segment.

Another acquisition channel.

Another pricing strategy.

Another architecture.

Each experiment can be perfectly rational in isolation while the project as a whole goes nowhere.

This is where I find the analogy to Brownian motion useful.

A particle undergoing Brownian motion receives countless tiny random impulses.

Its local path is irregular:






Innovative software development often looks exactly like this.

You try one direction.

Evidence pushes you sideways.

A new constraint appears.

You backtrack.

A prototype reveals another possibility.

You move again.

Trying to eliminate that local randomness is usually a mistake.

When the solution is genuinely unknown, exploration is necessary.

The real problem is not randomness.

It is randomness without drift.


Directed Brownian Development

Imagine that the same Brownian particle exists inside a weak directional field.

Its short-term motion is still noisy.

But over time it has a statistical tendency to move in one direction.

That is a useful model for software development under uncertainty.

I call it Directed Brownian Development:

Allow local exploration, but maintain global drift toward a stable North Star.

The local path can change constantly.

The global direction should not.

This gives us two very different artifacts.

A roadmap says:

Build CRM → add workflows → build marketplace.

A North Star says:

A small business should be able to configure and operate its software environment without depending on a development team.

The roadmap assumes a path.

The North Star describes a desired state.

If evidence later shows that CRM is the wrong abstraction, the roadmap has failed.

The North Star has not.

We can move from CRM to workflows, from workflows to declarative business models, from those models to a component marketplace — and still move toward exactly the same destination.

From the perspective of the roadmap:

We changed the product four times.

From the perspective of directed search:

We updated our model of the shortest path four times.

That distinction matters.

A pivot stops being an embarrassing deviation from the plan.

It becomes a normal consequence of learning.


Be rigid about direction, flexible about path

The North Star should be stable enough to produce drift, but abstract enough not to encode the solution.

Bad:

Build a Kubernetes-based AI CRM using event sourcing.

Better:

Let a small business launch and adapt its operational software without needing a software team.

Bad:

Build an ML valuation engine.

Better:

Let a property owner understand the real market position of a property within minutes.

Bad:

Automate the SDLC with LLM agents.

Better:

Minimize the amount of manual effort required to move safely from intent to production.

The difference is subtle but important.

Technologies, architectures, products, and workflows can all be hypotheses.

The North Star should survive their rejection.


The North Star does not choose the next experiment

Direction alone is not sufficient.

At any moment, dozens of hypotheses may point generally toward the same goal.

So which should we test next?

A useful heuristic considers three things:

Impact — how much would the answer alter our plans?

Uncertainty — how weak is our current evidence?

Experiment Cost — how expensive is it to learn more?

Conceptually:

Priority

Impact × Uncertainty
────────────────────
   Experiment Cost

This is not meant to become another precision-scored framework.

It is a question generator.

Suppose two unknowns exist:

A. Can we redesign a dashboard users already like?

B. Can we legally and reliably acquire the data without which the product cannot exist?

A may require a month.

B may require three days.

There should be little debate about where the next experiment belongs.

The team should continuously hunt for the highest-value uncertainty.

Not:

What feature comes next?

But:

What do we most urgently need to know?


Assumption Debt

Technical debt is visible because it eventually makes code harder to change.

There is another form of debt that is often more expensive and less visible:

Assumption Debt.

It accumulates whenever product or architecture decisions are built on beliefs nobody actually tested.

For example:

Users need real-time updates.

We will need microservices.

Kafka is necessary.

Customers want dashboards.

We need to retain five years of data.

AI recommendations will increase conversion.

Each assumption can quietly produce months of implementation.

Sometimes they are correct.

But if they were never made explicit, we do not even know where the uncertainty lives.

A useful architecture review therefore asks two questions:

What are the technical risks?

and:

Which untested assumptions are forcing this architecture to exist?

The second question can be far more valuable.


Evidence should compound

Hypothesis-driven teams need more than experiment results.

They need memory.

Six months after an experiment, somebody will suggest the same idea again.

Maybe even you.

Without a record, the organization repeats the search.

A lightweight Evidence Ledger can prevent this.

For example:

HYP-017

Belief:
Semantic search will improve candidate matching.

Why it matters:
Keyword search misses semantically similar profiles.

Prediction:
Recall@20 improves by at least 15%.

Experiment:
1,000 historical candidate/job pairs.

Result:
+22%.

Decision:
Supported.

Confidence:
High for current dataset.

Open question:
Does the result generalize to other job categories?

This does more than preserve history.

It creates a feedback loop for judgment:

prediction

evidence

prediction error

calibration

better future predictions

Over time, the organization accumulates a second asset alongside the codebase:

a model of reality.

It knows not merely what the product does, but:

  • which approaches worked;
  • which failed;
  • under what conditions;
  • which assumptions remain uncertain;
  • which constraints are real;
  • which ideas have already been tested.

That knowledge compounds.

Each experiment constrains the search space for the next one.


Architecture is a hypothesis too

Engineers sometimes behave as though product decisions are uncertain while architecture decisions are objective.

They are not.

Consider:

We need an event-driven architecture.

Why?

A hypothesis-driven version might say:

We believe decoupled asynchronous processing is necessary because ingestion and processing must scale independently under the expected traffic profile.

Now we have something testable.

Perhaps the experiment compares:

synchronous prototype
        vs
queue-based prototype

under:

  • expected throughput;
  • burst traffic;
  • downstream failures;
  • recovery;
  • latency constraints.

The result may confirm an event-driven design.

Or it may reveal that a simple synchronous architecture is perfectly sufficient for the next two years.

The better architectural question is often not:

Kafka or RabbitMQ?

It is:

What evidence says we need a broker at all?

This is hypothesis-driven architecture.

Build for confirmed constraints.

Preserve options for plausible future constraints.

Do not pay today for imaginary certainty about tomorrow.


AI changes the economics of exploration

This model becomes particularly important in the AI era.

Historically, experimentation was constrained by implementation cost.

If a prototype required a senior engineer for a week, a team had to be selective.

Today AI coding agents can produce, in a fraction of that time:

  • API adapters;
  • collectors;
  • evaluation harnesses;
  • synthetic datasets;
  • mock services;
  • benchmark implementations;
  • analysis scripts;
  • alternative architectures;
  • small user-facing prototypes.

That sounds like an uncomplicated productivity win.

It is not.

When implementation becomes cheaper, building the wrong thing also becomes cheaper.

Which means teams can now travel much farther in the wrong direction before noticing.

The bottleneck moves.

From:

Can we build this?

toward:

Which thing is worth testing next?

AI expands the Brownian component of engineering.

We can explore many more local directions.

Therefore the directional component — hypothesis selection, evidence quality, decision rules, and North Star alignment — becomes more important, not less.

A team of AI agents without a strong search discipline is not necessarily an accelerated engineering organization.

It may simply be an accelerated random walk.


The engineer becomes a search strategist

This changes what high-leverage engineering looks like.

Coding still matters.

Architecture still matters.

Distributed systems, databases, reliability, security, performance — none of these disappear.

But another layer becomes increasingly important:

  • identifying uncertainty;
  • decomposing assumptions;
  • designing cheap experiments;
  • defining falsifiable predictions;
  • evaluating evidence;
  • deciding what not to build;
  • choosing the next search direction.

The engineer is no longer managing only implementation.

The engineer is managing a search space of possible solutions.

And this may become one of the most important distinctions between average and exceptional AI-enabled teams.

If ten implementations can be generated cheaply, the valuable skill is no longer merely producing an eleventh.

It is knowing which three deserve to exist.


This is not the enemy of intuition

None of this means replacing intuition with spreadsheets.

Intuition is essential.

Good product ideas, architectural insights, and technical shortcuts often appear before they can be formally justified.

The mistake is not trusting intuition.

The mistake is allowing intuition to grade its own homework.

A hypothesis simply says:

I have a strong belief.

Here is what that belief predicts.

Here is what reality should look like if I am right.

Here is when I will look again.

That adds very little friction.

But it creates something incredibly valuable:

a point at which you are allowed to discover that you were wrong.

And being wrong is not the failure.

Failing to update is.


A different definition of engineering velocity

Software organizations traditionally measure progress using things such as:

  • tickets completed;
  • story points;
  • deployment frequency;
  • features shipped.

These metrics measure movement.

They do not necessarily measure direction.

Under uncertainty, a more useful definition might be:

Engineering velocity is the rate at which a team reduces decision-relevant uncertainty while moving toward a valuable outcome.

Sometimes that reduction produces code.

Sometimes it deletes a project.

Sometimes three days of experimentation prevent three months of development.

The highest-velocity team may occasionally be the one that builds the least.

Because it discovers earlier what does not deserve to be built.


Be wrong locally. Move right globally.

The deepest value of Hypothesis-Driven Development is not that it makes every decision correct.

It does something more realistic.

It makes mistakes observable, cheap, and useful.

Directed Brownian Development adds one constraint:

those local mistakes should occur inside a system with global direction.

The North Star provides the drift.

Hypotheses expose beliefs.

Experiments create contact with reality.

Evidence selects which directions survive.

The team’s model changes.

The next hypotheses become better.

And the cycle repeats:

North Star

Current Beliefs

Highest-Value Uncertainty

Hypothesis

Minimum Viable Experiment

Evidence

Corrected Belief

Decision

Updated Search Direction

The trajectory will not be straight.

It should not be.

Straight lines are a luxury of problems whose solutions are already known.

Innovative software development is different.

The competitive advantage may increasingly belong not to teams that are never wrong, but to teams that can become wrong faster, more precisely, and more cheaply than everyone else — while continuously updating their direction.

Or, in one sentence:

Be wrong locally. Move right globally.