When analysts get an explanation wrong, it's rarely because they lacked evidence. It's because they picked a favorite explanation early, then unconsciously collected and interpreted evidence to support it. Psychologists call this confirmation bias, and it survives intelligence, experience, and good intentions — which is why fighting it takes structure, not willpower.
Analysis of Competing Hypotheses (ACH) is that structure. Developed by CIA veteran Richards J. Heuer Jr. and popularized in Psychology of Intelligence Analysis and Heuer & Pherson's Structured Analytic Techniques for Intelligence Analysis, ACH forces you to evaluate all plausible explanations against all significant evidence simultaneously — and to look for evidence that disproves hypotheses rather than evidence that confirms your favorite.
This tutorial pairs with the interactive ACH Matrix tool. Open it in another tab and build your matrix as you read — everything auto-saves in your browser, and each step below maps directly to a feature in the tool.
When to use ACH
ACH earns its keep whenever:
- There are several plausible explanations for what you're observing (attribution questions, root-cause investigations, fraud vs. error, competitor intent)
- The judgment matters enough to defend — you may be asked later why you ruled out the alternatives
- Evidence is incomplete, ambiguous, or possibly deceptive
- You suspect you (or your team) already have a favorite answer
It is overkill for questions with a single obvious answer or where evidence can settle the matter directly. It is exactly right for the murky middle — which is most of analysis.
The core idea: disconfirmation
The intuitive approach to hypothesis testing is to ask "which explanation does the evidence support best?" Heuer's insight is that this question is nearly useless, because most evidence is consistent with more than one hypothesis. A malware sample compiled during Moscow business hours is consistent with a state-sponsored actor — and with a criminal crew in the same timezone, and with anyone who sets their build machine's clock deliberately.
ACH flips the question: which explanation has the least evidence against it? Evidence that is inconsistent with a hypothesis does real analytic work — it lets you eliminate. Evidence that is merely consistent does almost none. The hypothesis you report is not the one with the most support; it's the one that survives the most attempts to kill it.
Heuer's method, step by step
Generate the full set of hypotheses
Write down every explanation a reasonable analyst could offer — including the ones you consider unlikely. Each hypothesis should be:
- Short — one sentence
- Falsifiable — evidence could in principle rule it out
- Mutually exclusive — if one is true, the others are not
Brainstorm with colleagues if you can; a group reliably generates hypotheses an individual misses. Resist the urge to screen any out at this stage. An unproven hypothesis is not a disproven hypothesis, and dismissing one early is exactly how surprise happens.
In the tool, enter these as the column headers. Start with at least two or three; you can add, reword, or remove hypotheses at any point and the matrix recalculates automatically.
List the significant evidence and arguments
Collect everything that bears on the question: reports, observations, technical artifacts, assumptions, and logical arguments. Two things analysts routinely forget:
- Absence of evidence is evidence. If a hypothesis were true, what would you expect to see that you are not seeing? Add that as an item.
- Record the source. Every item should carry a source reference so its reliability can be challenged later.
In the tool, add items one at a time or paste a batch into Bulk import (one item per line, with an optional source after a pipe character). Each item's expandable detail panel holds the source reference and a reliability rating.
Rate the matrix — one row at a time
Now work through the matrix asking, for each evidence item: if this hypothesis were true, how likely is it I would see this evidence?
Heuer's scale runs from very consistent to very inconsistent:
| Rating | Meaning | |---|---| | ++ | Very consistent — strongly expected if the hypothesis is true | | + | Consistent | | 0 | Neutral — tells you nothing either way | | − | Inconsistent | | −− | Very inconsistent — hard to explain if the hypothesis is true | | N/A | Not applicable to this hypothesis |
The discipline that matters most: work row by row, not column by column. Rate one piece of evidence against every hypothesis before touching the next piece. Working down a single hypothesis's column puts you back in confirmation-bias territory — you start reading each item in that hypothesis's favor. The tool's rating panel is built around this: its next-cell navigation walks across the row before dropping to the next evidence item.
Add a one-line rationale to any rating that isn't obvious. Future-you, and anyone reviewing your work, will need it.
Prune the evidence: find what is diagnostic
Scan each completed row. An item rated consistent with every hypothesis has no diagnostic value — it cannot help you discriminate, no matter how interesting it is. Heuer's analogy is a fever: it tells the doctor the patient is sick, but nothing about which illness, because it's consistent with dozens.
Mark these items as low-diagnosticity and mentally set them aside (the tool badges rows that are consistent across the board and lets you rate diagnosticity per item). What remains — the handful of items with inconsistent ratings — is what your conclusion will actually rest on. It is usually a much shorter list than the evidence table suggests, and knowing which few items drive your judgment is half the value of the exercise.
Draw tentative conclusions from the inconsistencies
Total the inconsistencies in each column (the tool does this live: − counts 1, −− counts 2). The hypothesis with the lowest inconsistency score is your tentative front-runner — the least-inconsistent explanation.
Then attack it. Try to disprove the front-runner rather than confirm it. And look hard at the runner-up: if the gap between them rests on one or two evidence items, your conclusion is fragile, and you should say so.
The inconsistency score is not a probability. Heuer is explicit on this: ACH identifies the hypothesis with the least evidence against it, not the hypothesis that is likely true with some computable confidence. If you need actual probability updates, that's Bayesian territory — see the companion Bayesian updating tutorial.
Check sensitivity: assumptions and deception
Identify the few ratings that drive the result, and ask what they depend on:
- Assumptions — "This forensic report is damning assuming the chain of custody is intact." Flag the assumption explicitly. In the tool, each evidence item has a key-assumption flag and note; carry these into a Key Assumptions Check for the project.
- Deception — the most diagnostic evidence is precisely the evidence an adversary would fake. For any item that heavily favors one hypothesis, ask: if someone wanted me to believe this, could they have planted it? Record the concern against the item.
If your conclusion flips when one flagged assumption fails, that assumption is your finding.
Report all the hypotheses, not just the winner
A defensible ACH write-up covers the relative standing of every hypothesis: which one is least inconsistent, which were eliminated and by what evidence, and which remain plausible. Decision-makers need to know how close the call was — "H1, but H3 survives if the insider's alibi fails" is a far more useful judgment than "H1."
The tool's Export Report produces a Markdown snapshot with the full matrix, scores, rationales, flagged assumptions, and version history — the analytic trail that lets someone challenge your reasoning instead of your conclusion.
Identify indicators and keep the matrix alive
Before you finalize, answer: what future evidence would change this assessment? List concrete, observable indicators — "attribution claim from a known criminal forum persona would weaken H1" — and hand them to whoever is monitoring the problem. The tool prompts for these before it lets you save a version quietly without them.
Then treat the matrix as a living document. When new evidence arrives, add the row, re-rate the affected cells, and save a new version with a change note. The version history and diff view show exactly how the ranking shifted as evidence accrued — which is what makes your judgment auditable months later.
A worked example
Suppose a payments network was breached in March, and three explanations are on the table:
- H1 — State-sponsored actor conducting espionage
- H2 — Criminal group, financially motivated
- H3 — Insider acting alone
Six evidence items, rated row by row:
| # | Evidence | H1 | H2 | H3 | |---|---|---|---|---| | E1 | Custom malware, no known criminal toolkit overlap | ++ | − | − | | E2 | No data offered for sale on criminal markets after 90 days | + | −− | + | | E3 | Access originated from a vendor VPN account | + | + | + | | E4 | Exfiltration targeted design documents, not card data | ++ | −− | 0 | | E5 | Activity occurred during the insider's documented leave | + | + | −− | | E6 | Compile timestamps fall in UTC+3 business hours | + | + | N/A |
Reading the matrix:
- E3 is non-diagnostic — consistent with everyone, so it drops out despite being the item that started the investigation.
- E6 is weak — timestamps are trivially manipulated; it gets a deception flag and little weight.
- Inconsistency scores: H1 = 0, H2 = 5, H3 = 3. H1 is the least-inconsistent hypothesis.
- Sensitivity: H3's elimination rests heavily on E5. If the leave records are wrong — or the insider had remote access nobody documented — H3 revives. That assumption gets flagged, and "verify E5 leave records against VPN logs" becomes a monitoring indicator.
The honest bottom line for the customer: the evidence is most consistent with a state-sponsored actor (H1); a financially motivated group is effectively ruled out by E2 and E4; an insider remains possible only if the leave-record assumption fails. That is a judgment someone can interrogate — which is the point.
Common pitfalls
- Screening out "unlikely" hypotheses at step 1. The hypothesis you refuse to table is the one that surprises you. Deception hypotheses in particular must be tabled to be assessed.
- Rating by column. The moment you work one hypothesis at a time, you're pattern-matching for it. Row by row, always.
- Counting consistent ratings as support. Plus signs pile up on every plausible hypothesis. Only the minus signs discriminate.
- Presenting the score as certainty. Least-inconsistent means least bad, not true. Say how close the alternatives are.
- Doing it once. An ACH matrix built the week of the incident and never revisited is a snapshot, not an analysis. Save versions as evidence arrives.
Try it
Build your first matrix in the interactive ACH tool — hypotheses as columns, evidence as rows, Heuer's rating scale, live inconsistency scoring, assumption and deception flags, and versioned snapshots with diffs so your analytic trail survives contact with new evidence. No account needed; everything stays in your browser.
For the quantitative sequel — turning evidence into explicit probability updates across hypotheses — continue with Bayesian Updating: From Prior to Posterior.