# Why Tree

> Diagnose a hard problem by building an evidence-graded "Why Tree" - a Goldratt Current-Reality Tree that fans many AI agents across the problem's branch-space, grades every node by the kind of evidence behind it (validating measured numbers' pipelines before trusting them), tries to refute its own load-bearing branches, and converges on the ONE system constraint plus the cheapest test that would prove it. Use when someone asks "why is X happening / why are we falling short of a goal", wants a root-cause analysis with real rigor (not a 5-minute 5-Whys), needs to find the real bottleneck before spending build effort, or asks to "stress-test our diagnosis" / "build a current-reality tree". Also runs an **Idea Audit** - evaluating a product/feature idea by first diagnosing the problem it claims to solve (idea quarantined from the swarm), then judging the idea against the located constraint - trigger on "evaluate my product idea", "should I build X", "would anyone pay for this", "would my product have solved this"

- Skill: `bayramannakov/why-tree` (Agent Skill, multi-file: 18 files)
- Install (CLI): `npx skillmds@latest add bayramannakov/why-tree`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bayramannakov/why-tree/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: BayramAnnakov (https://skillmd.com/u/bayramannakov)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/bayramannakov/why-tree

---


# Why Tree

A **Why Tree** is 5-Whys grown up. Naive root-causing follows a single thread, stops at the first plausible cause, and cites nothing. A Why Tree (Goldratt's Current-Reality Tree) does the opposite: it **searches the whole branch-space in parallel**, **grades every node by the evidence actually behind it**, **tries to refute its own load-bearing branches**, and **converges on the ONE constraint** that, if removed, unblocks everything else - plus the negative branches (fixes that backfire) and the single cheapest test that would fork-decide the conclusion.

The output is a **self-contained interactive HTML tree** + a one-page **decision doc** (constraint located / do this / don't do that / cheapest test).

This rigor costs tokens - real Deep field runs have landed at ~90-115 agents / 5.5-6.6M tokens. The skill is **transparent about that cost and gates on a depth choice before launching** (Phase 0), and when the depth isn't obvious it offers a cheap **scout gate** (Phase 1.5) that measures whether the swarm is even needed. Do not skip the gate.

## What makes it different from a normal root-cause analysis (read first)

1. **Branch-space first, depth second.** Map *all* the candidate "why"s from many independent lenses before deepening any one. A single-thread analysis finds the first cause; a tree finds the real one.
2. **Every node is graded.** Each node carries an **answer-kind** (is this MEASURED, an INSTANCE, EXTERNAL, a CLAIM, an INFERENCE, a HYPOTHESIS, or just FRAMING?) + a **confidence grade** + a **citation** — and every MEASURED node additionally carries a **validation state** (`raw`/`validated`/`triangulated`/`contested`): a number is not yet a fact until its pipeline is checked. Ungraded assertions are banned. See `references/answer-kinds.md`.
3. **Refute before you trust.** Load-bearing branches face an adversarial pass that tries to kill them. Branches that die are marked REFUTED/DOWNGRADED *with the evidence that killed them* - kept visible, not deleted (they're the most useful part).
4. **Converge to ONE.** Goldratt: there is one constraint; everything else is noise. The tree forces convergence to 3-5 roots and names the single system constraint - often a **policy/ownership** problem wearing a tooling costume.
5. **Honest census.** If the decisive nodes are still HYPOTHESIS (unmeasured), the tree says so out loud: "a map of where to look, not a verdict."

If you find yourself shipping five co-equal "root causes," a tidy single-thread chain, or a confident verdict built on unmeasured nodes - you did it wrong.

---

## Phase 0 - Frame the apex + the token-cost gate (do not skip)

**(a) Sharpen the apex.** State the problem as ONE undesirable effect — a **declarative STATEMENT of the bad thing**, ideally a gap-vs-goal: *"Too few X vs the N target by <date>"*, *"Free→paid conversion is below T"*. **Not a question** ("Can we evaluate X?" / "Why is conversion low?") — a question can't have children that read as "…because…", which breaks the whole "why" chain. Keep any question as a title; the apex *node* is the statement. The apex is itself a FRAMING node - it's a hypothesis about what the real problem is, and the tree may reframe it. Push back if the apex is a solution in disguise ("why don't we have feature Y" is a smuggled answer, not a problem) — but when the user's actual ask is to *evaluate* that solution ("I want to build X — would it work?"), don't stop at the pushback: that's **Idea Audit mode**, see (a3). Also reframe a **measurement / "how many" question** ("how many X, how relevant, how many meetings?") into the underlying gap or decision ("can we evaluate ROI of Y - and what's the constraint?"); the counts are *evidence* (Phase 1), not the apex. Don't build a tree on a pure data-pull.

**First — does this problem even need the skill?** A blind head-to-head ablation (3 problems) found that on a **clear-cut** problem a single agent *beat* the full workflow at ~1/50th the cost. The machinery only earns itself when **one mind can confidently go wrong**: cohort/measurement traps, several plausible roots competing, a buildable mechanism hidden under a symptom, or more branches/evidence than one context can hold. **If the answer is obviously legible to one careful pass, say so and answer it directly — do not run the workflow.** (This is why Quick mode was removed: for a cheap sketch, a single agent dominates it.) When it is NOT obvious either way — the common case — do not guess: **clear-cut is measurable, not readable**. Recommend the **scout gate** (Phase 1.5) at the depth gate and let three blind cheap passes demonstrate convergence or divergence before anyone pays for the swarm.

**(a2) Classify the apex: symptom vs target — it picks the output shape.** Two kinds of gap-vs-goal apex want two different answers, and conflating them is a real failure mode (a target apex run as a pure constraint tree once silently dropped a whole growth lever because converge refuted everything down to one):
- **Symptom apex** — *"X is leaking / under-converting / broken."* The classic CRT: converge to the ONE binding constraint. `apexType:'symptom'` (default).
- **Target apex** — *"hit N by date / grow X→Y"* — a number someone **chose**, reachable by several **additive** paths. Run the same tree **plus** a lever-decomposition: the parallel **levers** to N, each **sized** (volume × conversion → contribution), so the verdict is *"here's the bottleneck AND the arithmetic for whether the levers sum to N"* — not a lone bottleneck. `apexType:'target'`.
- **Say the fit out loud for a target apex:** *"This is a growth-target apex. A constraint tree hands you one bottleneck, not a portfolio that sums to N — I'll run it in lever mode so you also get the sized paths and an honest 'do they sum to the number?'."* Levers are **parallel paths, not rival causes**: one may be deprioritized (with a stated reason) but never refuted away like a wrong cause.

**(a3) Idea apex → Idea Audit mode (judge the idea against the tree, never the tree against the idea).** When the invocation IS a proposed solution — *"I want to build X / would X work / оцени идею продукта"* — don't reject the smuggled solution; invert it. Goldratt already named this move: a proposed solution is an **injection**, and an injection is never judged against the symptom — only against the Current-Reality Tree (CRT→FRT, `references/methodology.md`). The wrapper protocol:
- **Capture the idea verbatim**, structured: `idea: {statement, claimedProblem, mechanism, buyer}`. The `claimedProblem` ("onboarding takes 3-5 months") is a founder assertion — it enters the Phase-1 source registry as a **CLAIM-tier source** (`{id:'founder', tier:'raw'}`), never as a fact. Then extract the **undesirable effect the idea presupposes** (a "knowledge-navigation product for onboarding" presupposes *"onboarding takes 3-5 months with no early signal on fit or progress"*) and confirm it with the user: *"the tree diagnoses THIS problem; your idea gets judged against the constraint it finds."* **Scrub solution-shaped language from the apex**: phrase it as facts about the world (what happens, how long, what it costs), never as the absence of the idea's mechanism — "no early signal" is honest when the idea is a knowledge tool (the field case), but if the idea IS an early-signal instrument, that clause is the pitch restated as an absence, and the swarm is anchored through the front door while the quarantine locks the back. If you can read the pitch off the apex, rewrite the apex before launching. That problem is the apex — `apexType` is still `symptom` or `target` per (a2); Idea Audit is a wrapper around the normal run, not a third tree shape.
- **Quarantine the idea from the swarm (anti-anchoring).** The idea must never appear in a scout/lens/deepen/refute prompt — a swarm that knows the pitch bends toward the causes the pitch needs, and the fit-check becomes circular. Same rule as scout branches and prior verdicts. Only the post-converge fit-check stage (Phase 2, step 6c) ever sees it. Watch the **evidence brief**: the user's dictated context usually contains the pitch verbatim (it did in the field run), so when freezing the Phase-1 brief carry the problem's facts and strip the idea/solution language — the brief is a leak vector into every prompt.
- **Run the tree normally** — depth gate, scout gate, data gate, all unchanged. After converge, the **fit-check** (+2 agents) maps the idea onto the finished tree and emits `ideaFit`; the decision doc then *leads* with the idea verdict (Phase 5). Two mode interactions: if the **scout gate ships direct**, the fit-check pair still runs — against the scout consensus (the constraint + its decisive evidence) with a **degraded contract**: no tree means no node ids, so `addresses`/`restsOn` use the sentinel `['scout-consensus']` and the mini-doc's idea section is *forced* to the verify-first treatment ("judged against a scout consensus, not a drilled tree" — a fully orphanable verdict needs the full run). In **Test-plan mode** the fit-check is *deferred, not skipped*: the run saves the idea in the output JSON with an `ideaFitDeferred` marker and says so in the deliverable; the fit-check fires in the Phase-6 loop once the decisive tests come back (a fit verdict over an unsettled map would rest on hypotheses).
- **Scope guard.** The mode's claim is narrow and honest: *for an idea born from a problem the founder has direct access to, an evidence-graded diagnosis of that one system is the cheapest real signal* — does the idea touch the constraint, and where would that generalize (the segment fork). Market sizing, competition, and distribution are OUT of scope — say so and hand off.
- The fit-check is also invocable **post-hoc** on a finished tree — `why-tree idea-check <idea>` (Phase 6) — which is exactly how the mode was field-discovered: the user asked *"could my product have helped?"* only after the diagnosis was done.

**(b) Pick a depth - and state the cost plainly.** Present these and **wait for one explicit choice** (the choice may be the scout gate — that IS a valid answer, and the recommended one when the user is unsure). Describe scale by agent-count and breadth, never by time:

| Depth | Agents (approx) | What it does | When |
|-------|-----------------|--------------|------|
| **Scout gate** | ~4-5 (~100-150k) | 3 blind cheap passes + convergence judge + consensus refuter (Phase 1.5) — **measures** whether this problem even needs the swarm. Ships the answer directly if clear-cut is demonstrated; escalates to a depth choice **with receipts** if not. | **Recommended default when the user doesn't know the depth.** |
| **Standard** | ~22-40 | 6-lens branch map + grade every node + **measurement audit** (validate/triangulate the load-bearing numbers) + one refute pass + converge to one constraint + **drill the constraint branch to bedrock**. | The default for a known-confusable decision. |
| **Deep** | ~32-60 by cap arithmetic; **observed 90-115** | Adds loop-until-dry discovery, a 3-vote multi-lens refute panel, a wider measurement audit, full CLR audit, cheapest-test design, + the constraint drill. The exhaustive pass. | High-stakes, contested, oversized, expensive-to-get-wrong. |
| **Test-plan** | ~10-18 | Fan-out + grade + audit + light refute + converge — then **stops at a branch-map + ranked cheapest-tests + Data Request** (markdown; no drill, no narrate, no HTML). | When the decisive sources are **human-only** (internal BI, an ERP/1C, ad consoles) — the deliverable IS the test plan, because the verdict can only come from tests the user runs. |

(Agent count = lenses + deepen + **measurement audit** + **refute fan-out (the multiplier)** + converge + drill + narrate; a target apex adds +1 lever agent, **Idea Audit adds +2** — fit + fit-skeptic. See the blueprint's cap arithmetic. Older "~12-16 / ~25-30" figures predate the caps + drill + audit steps.) **Observed cost: ~30-60k output tokens per agent** (real field runs — Standard: 26 agents ≈ 833k; Deep: 91 agents ≈ 6.6M and 111 agents ≈ 6.4M). The cap arithmetic gives Deep ≈ 32-60 agents, but **loop-until-dry + the 3-vote refute multiplier compound in practice: quote Deep at ~90-115 agents / ~5-7M tokens, not the arithmetic floor.** State explicitly, e.g.: *"Deep runs ~90-115 subagents and consumes ~5-7M tokens. Confirm before I launch."* Never launch Deep without confirmation; if running headless/delegated with a pre-granted "depth+cost authorized", proceed without pausing. The hard caps (`MAX_DEEPEN`/`MAX_REFUTE`/`MAX_AUDIT`) bound the worst case — an early uncapped run spawned **171 agents** and the blowup rate-limited and *degraded its own refute pass* — so the caps are a correctness guard, not just cost. If the user gave a token budget (a "+Nk" directive), scale depth to it.

**Test-plan mode is not Quick mode back from the dead.** Quick was a cheaper *verdict* and lost to a single agent (the ablation above). Test-plan is a different **output shape** for a specific situation the full run mishandles: when Phase 1 shows the metrics that would decide the tree live behind sources only the USER can operate, a full run grades the decisive nodes HYPOTHESIS anyway and the human ends up running the real diagnosis afterwards. In that case half the value is **test design** — the tree serves as a table of contents, and the run continues through the Phase-6 update loop as test results come back. If the named sources are clearly human-only at invocation time, offer this mode in the gate.

**(c) Confidentiality check.** If the source evidence is a client's private data, ask whether the output may name them. Default to an anonymized tree. **In Idea Audit, the most confidential thing in the run is the unlaunched idea itself** — it lands verbatim in `why-tree-output.json` and inside an HTML built to survive being emailed, and the `redirect` is by construction a better product idea than the one on trial: ask whether the idea may be named in shared artifacts, and default to a redacted `idea.statement` ("a knowledge-navigation tool for onboarding") outside the local JSON.

---

## Phase 1 - Inventory the evidence sources

Before launching, enumerate what the research agents may actually read - this determines how much of the tree can be MEASURED vs left as HYPOTHESIS:

- **Web** - Exa (`mcp__exa__*`, `mcp__exa-research__*`) and/or the `firecrawl` skill for competitive/external facts, market data, public docs.
- **Local files / data the user names** - a folder, a CSV/JSON export, prior reports, transcripts, DB query results. Ask for paths.
- **Live data** - if a DB or API is reachable and the user authorizes it, agents can run their own reads (this is what produced the "6/6 sampled accounts had a 2nd seat" refutation in the source case).
- **Curated/derived sources — ask for these explicitly.** The dashboards, BI reports, finance P&L, and management reporting the business ALREADY trusts — where bots, definitions, and seasonality were cleaned once, upstream. The reflex question "what DB/API/files can I read?" misses them, and a field run paid for it: the only clean source for the decisive metric was a curated dashboard nobody asked about, and the human had to steer the skill to it by hand. Ask: *"which of these metrics has a report you already trust?"* When a raw-computed number and the curated source disagree, the node is **CONTESTED** (see `answer-kinds.md`) and the discrepancy is itself a finding — usually a definition mismatch on the raw side.
- **Prior runs (anti-contamination)** - if a previous Why Tree exists for the SAME problem, you may reuse its **frozen evidence brief** (the Phase-1 facts), but do NOT read its decision-doc / tree / verdict. Reading the prior *conclusion* anchors the lenses and leaks (a converge agent once copied "171 agents" from a prior doc straight into its output). Re-derive from evidence, never from the old answer.

**Compute the hard metrics FIRST.** For data-grounded problems, actually pull/compute the key numbers in Phase 1 (run the query, read the files) and pass them into the workflow as a **frozen evidence brief** with "do NOT re-query". This grounds nodes as MEASURED instead of HYPOTHESIS, and stops N parallel agents from re-hammering the same DB/API. Pull shared/expensive evidence ONCE.

**Build a source registry + run the cleanliness gate BEFORE freezing the brief.** The frozen brief is a **single point of contamination**: if a dirty number enters it, every downstream node inherits the artifact wearing a MEASURED badge — and "do NOT re-query" guarantees nobody re-checks. So before freezing, register every source as `{id, tier: canonical|curated|raw, known caveats}` and run the **pipeline-cleanliness checklist** (`references/answer-kinds.md`) ONCE per source: who's in the denominator (bots/internal/test traffic)? does the metric's *definition* match the claim's meaning (placed-vs-paid, sessions-vs-users)? is the window seasonal? attribution sound? extract pre-filtered? any computation traps (join explosion, average-of-averages, partial periods)? **what is this instrument structurally BLIND to** (only-successes · only-completers · partial ID coverage · a DB row that exists only on success)? and if the metric claims what a SYSTEM DOES or TRACKS, was it verified by RUNNING the system and watching, not inferred from a code-grep? Every metric in the brief then carries its source id + a `validation` state; a number from an unchecked source enters as `MEASURED validation:'raw'` — which caps at grade Mod and can never support the constraint. **Persist the registry** as `why-tree-sources.md` next to the output JSON and reuse it in later runs and the Phase-6 update loop — source tiers, caveats, and standard exclusions are evidence, not conclusions, so reusing them doesn't violate anti-contamination (and a company data-context/warehouse-docs skill, if one exists, seeds the registry for free). This gate is one orchestrator-level pass, zero extra agents — and it is the cheapest fix for the field failure mode: a real run shipped three MEASURED/high-confidence "facts" (bots in the denominator; an API definition mismatch; a seasonal trend) that burned 4 of 6 follow-up iterations, all three catchable here.

**Measurable-in-hand gate (do not skip).** Before any node is graded HYPOTHESIS or CLAIM, ask: *"would one more query/read over sources I can reach (already pulled, OR one query away from an authorized DB/API/analytics store) settle this?"* If yes, it is **not** a HYPOTHESIS — run the check and grade it MEASURED. A node that is cheaply measurable but left unmeasured is a worse failure than a genuinely-external unknown, and they must not be lumped together. **Because the frozen brief can't be enriched mid-run** (it feeds every prompt — adding to it invalidates the whole run's cache), at Phase 1 enumerate the funnel/mechanism decomposition the owner has in mind (e.g. *provide ICP → 3 reference leads → calibrate → generate → connect → send*) and PULL every queryable stage BEFORE freezing; discovering mid-run that a decisive metric was one query away all along is exactly the failure this gate prevents. **Tag every HYPOTHESIS/CLAIM node with a `gap`:** `in-hand` (reachable now — compute it from the source, incl. data queryable-but-not-yet-pulled; never ship it ungraded), `external` (needs new data we genuinely can't reach), or `experiment` (needs a test). Only `external`/`experiment` gaps are legitimate unknowns (they become the Data Request); the workflow's deepen guard **fails loud** on any `in-hand` gap left ungraded.

**Distribution-behind-threshold rule.** Whenever you compute a funnel step as a *threshold* (≥N, hit-the-wall, activated, churned), also pull the **distribution** of the underlying quantity before making any causal claim about why people don't cross it. "83% never hit the 50-seat wall" is silent on whether they died at 5 of 50 or 48 of 50 — opposite diagnoses with opposite fixes. A threshold count may not carry a causal claim the distribution would overturn.

Write a one-line **measurability note**: *"X and Y are queryable; the decisive number Z is not in any source we have - it will stay HYPOTHESIS and become the #1 cheapest-test."* This honesty is the point - it tells the user what the tree can and cannot settle.

**The pre-flight data-gate (ask ONCE, here — never mid-run).** This is the one point where the skill should ask *you* for data. Before launching the (expensive) swarm, list the **3-5 metrics that will actually decide the tree**, mark which are queryable from what you gave me and which are not, and ask a single question: *"these decide it; [A,B] I can compute, [C,D] aren't in any source I have — do you have them / a source, and which of them has a dashboard/report you already trust (so I can triangulate my raw computations against it)? Or should they stay hypotheses and become the data request?"* Wait for one answer, then launch. A single cheap round-trip here stops a 2M-token run from going blind on a number you had all along. Skip the gate only when the user pre-authorized "just run it" or the sources are obviously complete. **Interaction lives at the edges — the Phase-0 depth gate, this data gate, the scout-gate routing, and the Phase-5/6 Data Request — never inside the swarm:** 50 parallel agents can't pause for a question, so an agent that "wants to ask the user" mid-run must instead tag the node `gap:external` and route it to the Data Request.

**"interview me" mode.** If the user invokes with `interview me` (or names no data/files), run a short structured intake BEFORE Phase 2 — this is the channel for evidence that lives in someone's head, not in any queryable source (the team-knowledge an LLM can't pull). In one pass, ask for: the gap-vs-goal numbers; the 3-5 metrics they know off-hand; any files/DB/dashboards the agents may read; **what should ALWAYS be filtered out of any query** (test data, internal users, bots, fraud — the standard-exclusions question that catches denominator pollution before a single query runs); **what the key entity/metric words exactly mean here** ("when you say 'order'/'user'/'AOV', is that placed or paid, account or person? — the entity-disambiguation question); and the one or two unknowns they already suspect are decisive. Capture the answers as the frozen evidence brief + source registry, then proceed.

---

## Phase 1.5 - The scout gate (measure clear-cut, don't guess it)

The open question a field user asked — *"how do I recognize a clear-cut problem BEFORE spending 833k tokens?"* — has no reading-based answer: confusability is not legible from the problem statement (a real run's constraint re-anchored twice under testing; nobody could have called that ex ante). But **"one mind can confidently go wrong" is directly measurable: run three cheap minds blind and see whether they land in the same place.**

**Protocol (~4-5 agents, ~100-150k tokens — state this cost too):**
1. **3 blind scouts** in `parallel()`, each over the Phase-1 sources, each returning structured `{constraint: one sentence, decisiveEvidence: {claim, source, kind}, wouldRefuteMe: the test that would kill my answer}`. Independent — no scout sees another.
2. **Convergence judge** (1 cheap agent): do the three name the SAME binding constraint? `{converged, clusters, consensus}`.
3. **Consensus refuter** (1 agent, only when converged): attack the consensus from the dirty-pipeline + data-says-otherwise angles, default-to-refute.

**Routing:**
- **Converged + the decisive evidence is MEASURED from a validated source + survives the refuter** → clear-cut is *demonstrated*. Ship the answer directly as a mini decision-doc ("3/3 scouts converged; consensus survived adversarial refutation; decisive evidence: X") at ~1/10 the full-run cost. Do not run the workflow. (In **Idea Audit**, ship-direct still owes the user the idea verdict — run the fit pair against the consensus under the degraded contract in (a3): sentinel `restsOn`, forced verify-first.)
- **Diverged** (different constraints, or same constraint on different load-bearing evidence) → confusability is *demonstrated, not assumed*. Present the Phase-0 depth gate **with the receipts**: *"three independent passes named N different constraints — this is exactly the case where one careful pass goes confidently wrong."* The user now buys the swarm informed. Scout branches join the Phase-2 dedup pool as extra fan-out entries — but are NEVER injected into the lens prompts (anti-anchoring).
- **Converged but the consensus rests on evidence agents cannot measure** (human-only sources) → **Test-plan mode** — no depth of swarm can settle what only the user's queries can.

**The guard that makes this safe — consensus is NOT clear-cut by itself.** Independent minds converge on the intuitive story too: in the Fish Banks field run, three scouts would plausibly have agreed "players were too cautious" — the facilitator's own first read — and it is refuted by simulation (worst-case racing agents at N=3 still leave the ocean alive 775/1000). Votes don't gate; **evidence + surviving one refutation attempt** gates. A consensus killed by the refuter escalates to the full run with that kill as the receipt.

Record the outcome in the tree's `provenance.triage` (`{scouts, converged, decision, receipt}`) so the gate's calibration is auditable across runs — the Phase-6 update loop will expose any "shipped-direct" verdict that later proves wrong.

**Skip the gate when:** the user explicitly picked a depth; the user pre-authorized "just run it"; Phase 1 already shows the decisive sources are human-only (go straight to Test-plan); or the problem is so obviously trivial you'd answer it inline. When the user names no depth, the scout gate is the **default recommendation at the Phase-0 gate** — present it as the first option with its cost stated like any other depth, and get the one confirmation there (its ~100-150k is real money too; never spend it silently). One confirmation total: the Phase-0 answer "scout gate" authorizes the scouts AND, on escalation, the follow-up depth question with receipts.

---

## Phase 2 - Run the Workflow (the engine)

Use the **Workflow tool** with the blueprint in `references/workflow-template.md`. (The blueprint's stage comments carry their own numbering — match stages by their `phase()` label, e.g. this list's step 6c = the blueprint's 'Idea fit' stage.) The shape (scaled by the chosen depth):

1. **Branch-space fan-out** (`parallel()` barrier) - one agent per **lens**, each blind to the others, each emitting candidate WHY-branches under the apex. Lenses: funnel/mechanics · data-skeptic (audit the numbers) · competitive/external · customer-psychology/segments · economics/incentives · product-eng-constraint. More lenses = wider net.
2. **Dedup + bucket** (plain code, not an agent) - merge overlapping branches; bucket into journey **stages** + a **cross-cutting** group.
3. **Deepen + grade** (`pipeline()` per branch) - recursively ask "why does this happen?" **loop-until-dry** to bedrock (Deep) or one level (Standard); attach **answer-kind + confidence + citation** to every node using `references/answer-kinds.md`. Research agents pull evidence from Phase-1 sources here. **Cap the fan-out** (`MAX_DEEPEN`) — dedup first, rank by load-bearing, then drop the tail (and `log()` what was dropped).
3b. **Measurement audit** (bounded `parallel()`, ≤`MAX_AUDIT`) - for each load-bearing MEASURED node still `validation:'raw'`, one auditor attacks the **pipeline, not the causal logic**: the cleanliness checklist (denominator, definition, window/seasonality, attribution, survivorship, computation traps) + **triangulation** — if a second independent source in the registry can compute the number, compute and compare. Agree → `validated`/`triangulated`; disagree beyond tolerance or in sign → **`contested`** (grade drops to Weak, both values stay visible, the node can't support the constraint, and the reconciliation auto-joins `tests[]`/`dataRequest[]`). This pass exists because the refute pass won't catch dirty numbers: refute hunts THIN evidence, and a MEASURED/Strong artifact doesn't look thin (the exact field failure — three artifacts shipped as high-confidence facts).
4. **Adversarial refute** (perspective-diverse `parallel()`) - for each load-bearing branch, independent skeptics each try to *refute* it from a distinct angle (data-says-otherwise / mechanism-broken / survivorship / mis-attribution / **dirty-pipeline**). The dirty-pipeline angle is ordered FIRST for branches resting on MEASURED evidence — strong-looking numbers are exactly where the classic angles don't look — and costs no extra agents (it re-orders the angle list, not the vote count). A branch that more than half the skeptics refute is marked **REFUTED** or **DOWNGRADED**, keeping the killing evidence.
5. **Converge** - **group** surviving branches into **3-5 root causes** (group ≠ flatten — keep each branch's `children[]` chain intact under its root); locate **THE single system constraint** (if removed, the most branches unblock). The constraint root **must carry the full apex→bedrock why-chain as nested `children[]`** — a childless constraint root is the flat-funnel bug (the rendered output must be a multi-level *tree*, not a 3-band apex→roots→constraint funnel). A final **"drill constraint"** step re-expands that one branch to bedrock if converge flattened it. Flag whether the constraint is **policy/ownership** vs **tooling**. Apply the Evaporating-Cloud check if it's a goal-conflict (see `references/methodology.md`).
6. **Negative branches + cheapest tests + Data Request** - name fixes that would backfire (NEGATIVE), and the 1-3 reads that would most change the conclusion (rank by: cost to get × how much it moves the verdict). **Every recommendation is traceable: each root's `action` and each negative carries `restsOn: [nodeIds]`** — the evidence nodes it stands on — so that when a node later dies, the actions built on it die visibly with it (a field run's tree recommended building a markdown module; one elasticity check killed the node under it, and only a human noticed the recommendation should die too). Then compile the **Data Request** — the ranked list of evidence still missing (the `external`/`experiment` gaps, never the `in-hand` ones), each tied to the node(s) it would upgrade HYPOTHESIS→MEASURED and ranked by verdict-impact ÷ cost; #1 is whatever would locate the constraint. This is the "what I need from you to turn this map into a verdict" deliverable (the generalized version of: *"I don't have the ROI data — but here are the exact 4 numbers that would answer it"*).
6b. **Lever decomposition + sizing — TARGET APEX ONLY.** When the apex is "hit N", decompose the **additive levers** (the distinct paths to N — acquire-net-new / migrate-the-base / raise-conversion-of-segment-Y), **size** each (volume × conversion → contribution toward N, MEASURED where the data supports it else gap-tagged), tag **Own/Win/Buy + effort**, map the located **constraint** to the lever it binds, and compute **`sizing`** — do the levers credibly **sum to N**, or does the number lean on one unproven lever? **Levers are parallel paths, not rival causes:** a weak lever is `role:'dropped'` **with a `droppedReason`** — never silently cut. (This is the fix for the run that lost a whole lever to "converge to ONE".)
6c. **Idea fit-check — IDEA AUDIT ONLY (+2 agents).** The finished tree finally meets the quarantined idea. A fit agent maps the idea onto the tree and emits **`ideaFit`**: `addresses: [nodeIds]` (the real nodes the idea would change) and a **verdict** — `dissolves-constraint` (removes/moves the located constraint) | `relieves-symptom` (real nodes, not the constraint) | `misses-constraint` (refuted/peripheral nodes) | `negative-branch` (run the idea forward like any fix — it backfires). Plus four named checks, **each an evidence-graded claim, never a pronouncement**:
   - **Policy-tool mismatch** — if the constraint is policy/ownership and the idea is a tool that leaves ownership where it is, the tool cannot dissolve it (`methodology.md` belief #4); say it explicitly.
   - **Absorbed-pain / willingness-to-pay** — classify the diagnosed pain: `acute` (escalating, budgeted-to-fix) vs `chronic-absorbed` vs `unknown` (then the WTP test is the first thing to run). `chronic-absorbed` = the system built compensating routines around it; the cost was internalized years ago — the field case: 15-20-year-old systems whose slow onboarding was long since priced in as a cost of doing business, so *widespread ≠ payable*). Chronic-absorbed yields a low-WTP **HYPOTHESIS with kind/grade/cite and its test attached** (pre-sell to N buyers · does a budget line exist · has anyone paid for adjacent tools) — the kill must meet the same evidentiary bar as the diagnosis.
   - **Segment fork (the n=1 guard)** — the tree diagnosed ONE system. Mark which constraint nodes are instance-specific vs structural and emit the fork: *"dies where X holds; may live where Y holds."* This converts a kill into ICP selection — the mode's most product-useful output.
   - **The redirect** — what WOULD dissolve the located constraint; the tree's reframed problem is the alternative idea space (field case: not *"navigate 4 months of knowledge"* but *"know in 2 weeks whether A is onboarding better than B"*).
   The verdict carries `restsOn: [nodeIds]` — and any check standing on *different* nodes carries its own — so the Phase-6 orphan sweep applies to the idea verdict exactly as to any recommendation (the workflow drops phantom ids deterministically; a verdict whose support empties out is contested by construction). A second agent then plays skeptic against the fit verdict itself — one refutation attempt, arguing whichever side the verdict didn't take, and killing **only on a named error** (thin evidence is already on the badge; default-to-refute here would fire every run and mean nothing). The outcome is recorded either way as `refutation: {contested|survived|skipped}` — the artifact must distinguish "attacked and lost" from "never attacked"; a contested fit ships with **both sides visible**, never as a clean verdict.
6d. **Narrate (both apex types; skipped in Test-plan).** A final cheap agent turns the finished tree into a short **`narrative[]`** memo (3-7 `{heading, body}` prose sections: the problem → what the evidence forces → what we know → the constraint / the lever portfolio → do / don't → the honest risk; in Idea Audit, one section states the idea verdict — and its strongest counter-argument, if contested — in plain words). The HTML renders it at the **top**, so the single artifact self-explains before anyone drills the tree.
7. **Emit structured tree JSON** - the contract for the visualization (strict schema in `references/workflow-template.md`; converge emits the core, and the final object is assembled across the later stages — drill, levers, idea fit-check, narrate — plus orchestrator stamps like `verdictStatus` and `provenance`): `apex` (a SHORT undesirable-effect **STATEMENT**, ≤140 chars — NOT a question, NOT the answer), `verdict` (the one-line answer), `apexType` (`symptom`|`target`), `stages[].nodes[]` (with `id/text/kind/grade/validation/role/cite/gap/children`), `roots[]` (**each with a nested `children[]` causal chain — REQUIRED and non-empty on the constraint root**), `constraint`, `negatives[]`, `corrections[]` (1-3 one-liners for claims the refute pass killed/demoted, with the killing evidence — the HTML's red "live corrections" banner, often its most-trusted section), `tests[]`, `dataRequest[]`, `census`, `narrative[]`, `verdictStatus`, (target apex) `levers[]` + `sizing`, and (Idea Audit) `idea` + `ideaFit`. `verdictStatus` (`verdict`|`map`) is **computed by the orchestrator, never by the converge agent**: it is `map` unless the constraint's `loadBearing` node is solid (not HYPOTHESIS/CLAIM, not MEASURED-`raw`/`contested`, no refute/measurable warnings). Tag any test/recommendation that rests on an un-refuted CLAIM/HYPOTHESIS node with "(verify first)".

**Phrasing (this is what makes the tree readable as a "why" chain):** every node — `apex`, every `root[].title`, every node `text` — is a **declarative problem/cause STATEMENT** that reads as an answer to "why" of its parent. *"Ad spend is never captured"*, not the topic label *"Cost denominator"*; *"We can't attribute DMs to ads"*, not the bucket *"DM stage"*. **Stages are an analysis scaffold for grouping evidence**, not causal claims — the rendered funnel is **problem → root causes → constraint** and stage names become only context tags, so never rely on a stage label to carry causal meaning. **Never make a "stage" for the apex / verdict / framing itself** — that content IS the apex statement + verdict, not a cause bucket (a stage titled "Apex" or "framing" is a generation bug). Keep `role` within the controlled vocabulary; don't invent roles like "apex-answer".

Save the JSON to disk (e.g. `why-tree-output.json`) before visualizing, so a failed render never loses the analysis.

---

## Phase 3 - Visualize (invoke `frontend-design`)

Render the tree JSON into a **single self-contained HTML file** using `assets/tree-template.html` as the scaffold. **Invoke the `frontend-design` skill** for the aesthetic pass - this is the user's explicit ask: the visualization must be distinctly designed, not the GitHub-default look of the original artifact. (frontend-design is an external Anthropic-provided skill; if it is not installed, `assets/tree-template.html` still renders standalone and the aesthetic pass is optional.)

Requirements the visualization must hit:
- **The narrative memo rendered FIRST** - `narrative[]` as a styled "Read this first" block at the top (above the tree), open by default, so the artifact self-explains in prose before anyone touches the interactive tree. This is the comprehension layer.
- **A prominent one-line `verdict`** rendered under the apex (the answer; the apex states the problem) — **styled by `verdictStatus`**. When it is `map`, the header itself must wear an unmistakable amber "WORKING HYPOTHESIS — map, not verdict" treatment naming the #1 deciding test; never the confident act-ready styling. The census honesty must reach the headline: a field run shipped a beautiful act-ready verdict whose constraint stood on a HYPOTHESIS node that died on the first check — the reader must not need to scroll to the census panel to learn that.
- **The lever portfolio (target apex only)** - render `levers[]` as a sized panel (each lever's contribution, Own/Win/Buy, effort; dropped levers shown greyed *with their reason*, never hidden) plus the `sizing` bottom line ("do the levers sum to N?"). Hide the panel when `levers` is absent (a symptom apex).
- **The "Idea on trial" panel (Idea Audit only)** - render `ideaFit` near the top (after the memo, **before** the lever portfolio — the reader brought the idea): the idea statement **plus its `claimedProblem` and `buyer`** (the buyer line is half the WTP argument, and the claimed problem lets the reader check the apex was extracted honestly), the verdict badge (`dissolves-constraint` green · `relieves-symptom` amber · `misses-constraint` / `negative-branch` red), the nodes it addresses — with "includes the constraint" **computed from the constraint chain, never asserted from the verdict enum** — the policy-tool mismatch note, the absorbed-pain line **with its kind/grade chip and its test**, the segment fork (with its `gap`), the redirect, and the `refutation` state: contested (both sides visible), survived, or **skipped — a fit that was never attacked must say so**. Hide the panel when `ideaFit` is absent; when the JSON carries `ideaFitDeferred` or `ideaFitError`, render *that* where the panel would be — the user's question must never silently vanish. The badge obeys the same census honesty as 

…(truncated)
