Some problems do not arrive as tidy tickets.
They arrive as a fog:
- the business outcome matters, but the path is unclear
- engineering sees several plausible architectures
- product sees several customer segments or workflows
- leadership wants a confident answer before the team has enough evidence
- everyone has opinions, but nobody can prove which option will work
This article is about those situations.
As of June 22, 2026, I reviewed sources on Cynefin, Wardley Mapping, assumption mapping, spikes, premortems, OODA loops, one-way versus two-way door decisions, and Architecture Decision Records. The individual practices are source-backed. The combined operating model below is my synthesis for product and engineering teams that need to make progress when the problem has many possible solutions, or when the team does not yet know what the real solution space looks like.
TL;DR
- Ambiguous problems are not solved by pretending they are clear. They are solved by classifying the uncertainty and choosing the right learning loop.
- Start by asking: Is this clear, complicated, complex, or chaotic? Clear problems need playbooks. Complicated problems need expert analysis. Complex problems need experiments. Chaotic problems need immediate stabilizing action.
- Capture unknowns as assumptions, not vague anxiety. Ask: What must be true for this plan to work?
- Explore alternatives deliberately, but do not explore forever. Use cheap tests, spikes, prototypes, interviews, and premortems to reduce the most expensive uncertainty first.
- Treat reversible decisions differently from irreversible ones. Move fast on two-way doors. Slow down for one-way doors.
- The winning loop is: frame -> map unknowns -> generate options -> test risks -> decide -> record -> revisit.
- A good decision record should include the context, options considered, confidence level, consequences, and the signal that would trigger a revisit.
What You Will Learn Here
- How to recognize when a problem is ambiguous instead of merely complicated
- How engineers and PMs can capture unknowns without turning planning into theater
- How to choose between research, spikes, prototypes, experiments, and direct execution
- How to avoid analysis paralysis when there are too many alternatives
- How to document decisions so future teams understand the trade-offs
- How to use a small assumption registry in code or docs to keep uncertainty visible
The Core Problem
Most teams are comfortable with execution uncertainty:
We know what to build.
We are not sure how long it will take.
Ambiguous problems are different:
We are not fully sure what problem we are solving.
We are not fully sure which constraints matter.
We are not fully sure which solution family is best.
We are not fully sure what we do not know yet.
That last line is the dangerous one.
Known unknowns are manageable. You can write them down, assign owners, and test them. Unknown unknowns are different. They appear only after you start interacting with reality: a user interview, a prototype, an integration test, a migration rehearsal, a production incident, or a failed sales call.
The goal is not to eliminate uncertainty. The goal is to convert invisible uncertainty into visible learning work.
First, Classify the Situation
Cynefin is useful here because it reminds us that not every problem deserves the same process. The Cynefin Company describes the framework as a way for leaders to make decisions in context by distinguishing different domains and matching action to reality.
For practical software work, I like this simplified version:
Clear
Known problem, known solution.
Use a checklist or existing playbook.
Complicated
Several valid answers may exist.
Bring experts together, compare trade-offs, map dependencies.
Complex
Patterns are still emerging.
Run safe-to-fail experiments and learn by probing.
Chaotic
No stable pattern and immediate risk.
Act to contain damage first, then analyze.
This classification matters because teams often apply the wrong motion:
- They over-research clear work and lose speed.
- They treat complicated work as if one person’s opinion is enough.
- They treat complex work as if a planning meeting can reveal the answer.
- They try to map chaos while the system is on fire.
When in doubt, use this decision gate:
Is the system actively burning?
yes -> stabilize first
no
|
v
Is there a proven playbook?
yes -> execute the playbook
no
|
v
Can experts reason to a good answer?
yes -> analyze alternatives
no
|
v
Run experiments to discover the shape of the problem
Map the Unknowns Before You Rank Solutions
When a team jumps directly to solutions, every option sounds better in the voice of its strongest advocate.
Before comparing alternatives, write down what would need to be true for each option to succeed.
For example, imagine a team choosing how to add enterprise audit logs:
- Option A: write directly to Postgres
- Option B: publish events to Kafka
- Option C: use a managed event pipeline
- Option D: start with Postgres, extract later
Instead of debating taste, ask:
What must be true for Option A to work?
- audit volume stays within Postgres write capacity
- reporting queries do not harm transactional paths
- retention requirements remain simple
What must be true for Option B to work?
- the team can operate Kafka safely
- downstream consumers can tolerate eventual consistency
- debugging event delivery will be manageable
What must be true for Option C to work?
- vendor retention and compliance controls match customer needs
- pricing is acceptable at projected volume
- export and migration paths are credible
What must be true for Option D to work?
- future extraction boundaries are designed now
- product can accept a smaller first release
- the migration path is not blocked by schema choices
Now the conversation changes. You are not asking, “Which option do we like?” You are asking, “Which assumptions are most important and least proven?”
That is the heart of assumption mapping. Google’s Design Sprint Kit frames leap-of-faith assumptions as important assumptions that can make or break an initiative if false. The useful move is to plot assumptions by importance and evidence, then focus near-term experiments on the important-and-unknown quadrant.
high importance
^
|
important + known | important + unknown
build into plan | test first
|
low evidence <------------+------------> high evidence
|
unimportant + | unimportant + known
unknown | ignore for now
park for later |
v
low importance
The map is useful, but the conversation is more useful. If product thinks an assumption is known and engineering thinks it is unknown, that disagreement is the work.
Explore Alternatives Without Getting Lost
Exploring alternatives is valuable only when it changes the decision.
A practical exploration loop looks like this:
1. Frame the decision
2. Generate credible options
3. List assumptions behind each option
4. Rank assumptions by cost-if-wrong and evidence
5. Test the riskiest assumptions
6. Make the smallest responsible decision
7. Record what would change your mind
That loop protects you from two common traps.
The first trap is premature convergence. The team picks the first plausible solution because it feels decisive. This is fast, but only by borrowing risk from the future.
The second trap is infinite divergence. The team keeps discovering options, but never makes a call. This feels rigorous, but often hides fear of accountability.
Good exploration has a stopping rule:
Stop exploring when:
- the riskiest assumption has enough evidence
- the remaining uncertainty is acceptable
- the next test costs more than the expected learning
- the decision is reversible enough to try
That last bullet is important.
Jeff Bezos’ one-way door versus two-way door framing is useful because it separates decisions that require slow deliberation from decisions that should move quickly. The 2015 Amazon shareholder letter describes Type 1 decisions as consequential and irreversible, and Type 2 decisions as changeable and reversible. A common organizational failure is using a heavyweight Type 1 process for too many Type 2 decisions.
In engineering terms:
Two-way door:
- feature flag choice
- first dashboard layout
- internal naming convention
- prototype implementation
- vendor trial with low migration cost
One-way door:
- irreversible data deletion policy
- long-term customer contract constraint
- architecture that locks in compliance posture
- public API guarantee
- migration that is hard to roll back
Move quickly when you can come back. Slow down when the door locks behind you.
Choose the Right Learning Tool
Not every unknown needs the same kind of investigation.
Use research when the uncertainty is about users, market, policy, or existing practice:
- customer interviews
- support-ticket review
- competitor review
- compliance consultation
- internal stakeholder interviews
Use a spike when the uncertainty is technical and concrete. Extreme Programming popularized spike solutions as small programs that explore potential solutions. James Shore describes spikes as small, isolated experiments used to inform decisions, often discarded after the answer is found.
Good spike questions are narrow:
Can we stream 10,000 audit events per second through this path?
Can this auth provider support tenant-specific SAML metadata?
Can our current ORM express the query shape without raw SQL?
Can we replay failed events idempotently?
Poor spike questions are vague:
Investigate event-driven architecture.
Research scalability.
Try the new vendor.
Explore options.
Use a prototype when the uncertainty is about interaction, workflow, or user comprehension:
- clickable UI
- fake-door test
- concierge flow
- manually operated backend behind a real interface
Use a premortem when the team is becoming overconfident. Gary Klein’s project premortem asks the team to imagine the project already failed and work backward to identify plausible causes. The value is not negativity. The value is making it socially safe to say the thing everyone is quietly worried about.
Use incremental delivery when unknown unknowns are likely. You cannot plan every surprise into existence, but you can design the work so reality talks back sooner.
A Practical Decision Record Template
Architecture Decision Records are a good lightweight pattern for capturing decisions. Michael Nygard’s original ADR format keeps records short and focused on context, decision, status, and consequences. Martin Fowler also emphasizes that ADRs should capture serious alternatives, trade-offs, confidence, and triggers for reevaluation.
For ambiguous product and engineering decisions, I would extend the template slightly:
# Decision: [short title]
## Status
Proposed | Accepted | Superseded
## Context
What problem are we solving?
What constraints matter?
What is known today?
## Options Considered
- Option A: ...
- Option B: ...
- Option C: ...
## Assumptions
- [high risk] ...
- [medium risk] ...
- [low risk] ...
## Evidence
What did we learn from research, spikes, prototypes, or production data?
## Decision
What are we choosing now?
## Confidence
High | Medium | Low
## Consequences
What gets easier?
What gets harder?
What risks remain?
## Revisit Trigger
What signal would cause us to reopen this decision?
The revisit trigger is the underrated part.
Without it, teams reopen decisions because someone new has a strong opinion. With it, teams reopen decisions because the context changed.
Examples:
Revisit if monthly audit-event volume exceeds 500 million.
Revisit if enterprise customers require seven-year searchable retention.
Revisit if event replay becomes part of the public support contract.
Revisit if debugging delivery failures takes more than one engineer-day per month.
That kind of trigger turns uncertainty into an observable contract.
Code Example: A Tiny Assumption Registry
You do not need a platform to start. A simple structured file or small script can make assumptions visible.
Here is a TypeScript-flavored example:
type EvidenceLevel = "none" | "weak" | "medium" | "strong";
type DecisionImpact = "low" | "medium" | "high";
type Assumption = {
id: string;
statement: string;
owner: string;
evidence: EvidenceLevel;
impactIfWrong: DecisionImpact;
nextTest: string;
};
const evidenceScore: Record<EvidenceLevel, number> = {
none: 0,
weak: 1,
medium: 2,
strong: 3,
};
const impactScore: Record<DecisionImpact, number> = {
low: 1,
medium: 2,
high: 3,
};
function riskScore(assumption: Assumption): number {
const uncertainty = 3 - evidenceScore[assumption.evidence];
return uncertainty * impactScore[assumption.impactIfWrong];
}
function prioritizeAssumptions(assumptions: Assumption[]): Assumption[] {
return [...assumptions].sort((a, b) => riskScore(b) - riskScore(a));
}
const auditLogAssumptions: Assumption[] = [
{
id: "A1",
statement: "Postgres can absorb first-year audit writes without harming core transactions.",
owner: "platform",
evidence: "weak",
impactIfWrong: "high",
nextTest: "Run a write-load spike with realistic tenant distribution.",
},
{
id: "A2",
statement: "Enterprise customers can accept daily export instead of live search in v1.",
owner: "product",
evidence: "none",
impactIfWrong: "high",
nextTest: "Interview five target customers before implementation starts.",
},
];
console.log(prioritizeAssumptions(auditLogAssumptions));
This is intentionally boring.
The point is not the code. The point is the behavior it encourages:
- every assumption has an owner
- evidence is explicit
- high-impact uncertainty rises to the top
- every risky assumption has a next test
You can put the same structure in Markdown, YAML, Linear, Jira, Notion, GitHub Issues, or an ADR folder. The format matters less than the habit.
The Team Ritual
Here is a simple 60-minute version for a cross-functional team:
0-10 min: frame the decision
- What outcome are we trying to create?
- What decision must be made now?
- What can wait?
10-20 min: generate options
- Include boring options
- Include build vs buy
- Include "do less now" and "do nothing yet"
20-35 min: expose assumptions
- What must be true for each option to work?
- What would make this option fail?
- What are we quietly assuming?
35-45 min: rank risk
- High impact and low evidence goes first
- Low impact unknowns go to the parking lot
45-55 min: choose learning actions
- spike
- interview
- prototype
- premortem
- small release
55-60 min: assign owners and stopping rules
- Who tests what?
- By when?
- What result changes the decision?
This meeting should not end with “more research” as a vague task. It should end with named tests and decision criteria.
A Worked Example
Suppose the team needs to decide how to launch an AI support assistant.
The first version of the problem might sound like:
Build an AI assistant for customer support.
That is too broad. Reframe it:
Reduce support response time for billing questions without increasing incorrect refunds or policy violations.
Now classify the uncertainty:
- Clear: support already has billing policies and refund thresholds.
- Complicated: integration with Zendesk, Stripe, and internal customer data needs expert review.
- Complex: customer trust and model behavior under ambiguous tickets need experiments.
- Chaotic: not currently chaotic unless the system is already causing live customer harm.
Generate options:
A. AI drafts replies, human approves every response.
B. AI classifies tickets and routes them to the right queue.
C. AI fully handles low-risk billing questions.
D. AI only retrieves policy snippets for human agents.
Expose assumptions:
A assumes reviewers can approve drafts faster than writing from scratch.
B assumes routing accuracy is enough to reduce queue time.
C assumes low-risk billing questions are easy to detect reliably.
D assumes better context retrieval is the real bottleneck.
Test the riskiest assumptions:
Interview support agents:
Is writing the reply the bottleneck, or is finding account context the bottleneck?
Run a trace review:
How many billing tickets are truly low-risk?
Prototype draft approval:
Do agents accept drafts, edit them heavily, or ignore them?
Premortem:
It is three months later and the assistant was rolled back. What happened?
Then decide:
Decision:
Start with AI-assisted policy retrieval and draft suggestions for billing tickets.
Confidence:
Medium.
Why:
Support interviews show context lookup is the largest bottleneck.
Full automation still has weak evidence around refund safety.
Revisit:
Reconsider partial automation if draft acceptance exceeds 70 percent
and policy-violation review stays below the current human baseline for 30 days.
That is not a perfect decision. It is a decision with memory.
How to Win These Cases
Winning ambiguous problems does not mean guessing correctly on the first try.
It means designing the path so the team learns faster than the risk grows.
The practical strategy:
- Name the kind of problem. Do not use a clear-problem playbook on complex work.
- Separate options from assumptions. Options are choices. Assumptions are the conditions that make choices succeed or fail.
- Prioritize the scary unknowns. Test important-and-unknown assumptions before easy-and-unimportant ones.
- Use the cheapest credible test. A spike, interview, prototype, or premortem should answer a decision-relevant question.
- Prefer reversible movement. Turn one-way doors into two-way doors when possible.
- Write the decision down. Include alternatives, evidence, confidence, consequences, and revisit triggers.
- Keep learning after launch. Unknown unknowns usually appear after contact with real users, real data, or real operations.
Gaps and Follow-Up Sections Worth Adding Later
This article is a playbook, not a full operating manual. The biggest gaps I would expand in a follow-up are:
- Facilitation scripts for running the 60-minute assumption mapping session with a large team
- Decision scorecards for weighting cost, reversibility, strategic fit, operational burden, and user value
- AI-agent assisted research workflows for generating option lists while keeping source-backed claims separate from inference
- Case studies showing how a team changed direction after a spike, premortem, or customer interview
- Templates for ADRs, assumption registries, premortem notes, and experiment briefs
The most useful next improvement would be a downloadable decision packet: one Markdown template for the decision, one assumption map, one spike brief, and one ADR.
Sources
- The Cynefin Company, “The Cynefin Framework”: https://thecynefin.co/about-us/about-cynefin-framework/
- Wardley Maps, “Using Cynefin to Decide When You Need a Map”: https://www.wardleymaps.com/guides/cynefin-and-wardley-maps
- Google Design Sprint Kit, “Assumptions Mapping”: https://designsprintkit.withgoogle.com/methodology/phase2-define/assumptions-mapping
- Precoil, “Assumptions Mapping”: https://www.precoil.com/assumptions-mapping
- Michael Nygard, “Documenting Architecture Decisions”: https://www.cognitect.com/blog/2011/11/15/documenting-architecture-decisions
- Martin Fowler, “Architecture Decision Record”: https://martinfowler.com/bliki/ArchitectureDecisionRecord.html
- ExtremeProgramming.org, “Spike solution”: http://www.extremeprogramming.org/rules/spike.html
- James Shore, “Spike Solutions”: https://www.jamesshore.com/v2/books/aoad2/spike_solutions
- Gary Klein, “Performing a Project Premortem,” Harvard Business Review, September 2007: https://hbr.org/2007/09/performing-a-project-premortem
- Amazon 2015 Letter to Shareholders, Type 1 and Type 2 decisions: https://www.sec.gov/Archives/edgar/data/1018724/000119312516530910/d168744dex991.htm
- OODApedia, OODA loop source material and notes: https://oodapedia.com/