| name | why-tree |
| description | 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". Bilingual triggers - "почему мы не достигаем цели", "построй дерево текущей реальности", "найди настоящее узкое место", "оцени идею продукта", "поможет ли мой продукт решить эту проблему". Pairs with /constraint-finder, which returns the 5 Focusing Steps once the constraint is located. Token-heavy by design (multi-agent) - it warns and asks for a depth before launching (a cheap scout gate can triage whether the swarm is needed at all), and only earns its cost when one careful pass could confidently pick the WRONG cause. |
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)
- 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.
- 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.
- 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).
- 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.
- 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 ", "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):
- 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.
- Convergence judge (1 cheap agent): do the three name the SAME binding constraint?
{converged, clusters, consensus}.
- 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):
- 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.
- Dedup + bucket (plain code, not an agent) - merge overlapping branches; bucket into journey stages + a cross-cutting group.
- 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).
- 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.
- 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).
- 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.
- 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 the header: a fit verdict resting on HYPOTHESIS/CLAIM or raw/contested nodes wears the "(verify first)" treatment, never act-ready styling.
- Collapsible, evidence-rich nodes that stay readable at 25+ nodes (indented disclosure tree, expand/collapse-all).
- Per-node chips: answer-kind (color-coded), confidence grade, role badge (ROOT / CONSTRAINT / LEVER / NEGATIVE / REFUTED / DOWNGRADED), and the citation on expand. MEASURED nodes additionally show their validation state:
raw renders visibly weaker (hollow/dashed), contested renders as a red CONTESTED badge with both values in the cite — an unvalidated number must not wear the same solid green chip as a triangulated one.
- A constraint "spotlight" - the single system constraint is visually unmistakable.
- A convergence map - a compact branches -> roots -> ONE-constraint diagram (SVG or styled flow), so the "everything funnels to one thing" claim is seen, not just asserted.
- The constraint branch must render as a multi-LEVEL chain, not a single box. The constraint root carries a nested
children[] why-chain (apex → because → because → … → bedrock); the spine must show those levels expanded/drillable in the funnel itself, not hide them in a side rail. A constraint box with no visible chain beneath it reproduces the "1-level-deep" bug — the whole point is that the eye can follow the chain down to bedrock.
- Panels: root causes, negative branches, cheapest tests, the Data Request ("what I need from you to turn this map into a verdict" — the ranked missing-evidence list; hide the panel if empty), and the evidence census ("~X% MEASURED, but the decisive Y% is HYPOTHESIS"). Normalize the census shares before drawing the bar — the orchestrator emits integer percentages while older trees carry fractions; the renderer must divide by the actual sum either way (an un-normalized 0.92 sum leaves a cosmetic empty sliver).
- Self-contained, opens on double-click, survives being emailed. A
<!-- TWEAK ZONE --> for last-mile label edits. (To screenshot during dev, serve via python3 -m http.server — chrome navigate mangles a raw file:// path.)
Keep assets/tree-template.html as the reusable scaffold (data swapped via the inline <script id="tree-data"> JSON block); write each run to its own output file. When splicing JSON into the block, escape every </ as <\/ (JSON-legal, HTML-identical) — a literal </script> inside any node text otherwise terminates the data block early and silently kills the whole artifact. To update a run's data later, replace ONLY the tree-data block inside the previously RENDERED, styled file — never regenerate from the bare template after the frontend-design pass (a field run lost the whole aesthetic layer that way: the rebuild silently shipped the undesigned scaffold, 58k → 51k bytes with the design gone).
Phase 4 - Verify (the CLR audit, non-negotiable)
Before showing anyone, audit the tree (Goldratt's "Categories of Legitimate Reservation"):
- Contradiction check - does any branch contradict another? Resolve or surface the tension explicitly.
- One-constraint check - is exactly ONE system constraint named? If five things are all "critical," convergence failed - send it back.
- Causality vs correlation - for each MEASURED->cause arrow, is the cause sufficient, or is there a hidden third factor? Mark INFERENCE honestly.
- Evidence-honesty census - compute the answer-kind mix. If the constraint-locating nodes are HYPOTHESIS, the headline must be "where to look," and the cheapest-test must target exactly those nodes.
- Refutation survived - every load-bearing branch must show it faced (and survived) the adversarial pass.
- Multi-level check - the constraint root must carry a non-empty nested
children[] chain down to bedrock. A childless constraint root is the flat-funnel bug — send it back to the drill step.
- Measurable-in-hand check (fail loud). Every HYPOTHESIS/CLAIM node must carry a
gap tag (in-hand / external / experiment). An in-hand node is a hard error — one query over data already pulled settles it, so the workflow's deepen guard warns loudly and the node must be computed and re-graded MEASURED before shipping. Only external/experiment gaps are legitimate, and they become the Data Request — never ship an in-hand gap as a "cheapest test" or a data-request line.
- Measurement-validity check — every load-bearing MEASURED node names its source-registry id and a
validation state. raw at the decision point means the measurement audit was skipped or capped past it — send it back. contested can never support the constraint, and its reconciliation must appear in tests[]/dataRequest[].
- Trend check — any Δ-over-time claim graded above INFERENCE must cite its YoY comparison or seasonal normalization (the Δ-over-time rule in
answer-kinds.md).
- Headline-matches-census check —
verdictStatus must be map whenever the constraint's loadBearing node is HYPOTHESIS/CLAIM or MEASURED-raw/contested, and the HTML header must visibly say so. A confident header on a map-status tree is the "beauty outruns reliability" bug — send it back to Phase 3.
- Data-request completeness - every node still graded HYPOTHESIS/CLAIM with an
external/experiment gap should appear in dataRequest[] (or be explicitly out-of-scope). The #1 item must be whatever would locate the constraint.
- Idea-fit checks (Idea Audit only) -
ideaFit.verdict is from the enum and its restsOn/addresses reference node ids that exist in the tree (the workflow scrubs phantoms — a scrubbed-empty restsOn must show as contested); the absorbed-pain/WTP claim carries kind + grade + a nameable test (an ungraded idea-kill is the same bug as an ungraded verdict); the segment fork is present (an n=1 tree may not silently speak for a market); refutation is recorded — skipped means the verdict is un-refuted and must read that way; and the quarantine held — provenance.quarantine === 'asserted' (the script asserts at launch that the pitch is absent from APEX and SOURCES; that catches verbatim leaks — paraphrase leaks are judged by the (a3) apex-scrub rule: can you read the pitch off the apex?). A missing stamp or a readable-pitch apex means the fit is circular: say so in the census bottom line and mark the fit verdict contested.
Phase 5 - Output
Deliver two things:
- The interactive tree (the HTML).
- A one-page decision doc (markdown + matching HTML if the user reviews in HTML per their convention): Constraint located -> What to do -> What NOT to do (the negative branches) -> The single cheapest test that would fork-decide -> What I need from you (the Data Request: the ranked missing evidence that would upgrade the map to a verdict). The tree is the diagnosis; the doc is the "so what." For a target apex, lead the doc with the lever portfolio — a lever × contribution × Own/Win/Buy × effort table + the
sizing "do they sum to N?" line — then the binding constraint; the reader needs the paths-to-the-number before the bottleneck inside them. For an Idea Audit, lead with the idea on trial: verdict → why (the nodes it rests on) → the WTP test → where it might live (the segment fork) → what to build instead (the redirect) — then the constraint story. The reader brought an idea; answer the idea first, with the tree as the evidence.
State the headline honestly: if the system constraint is located but the funnel/mechanism constraint is not, say both - "the policy constraint is settled and needs no more data; the mechanism constraint is unlocated and one query would pin it."
Phase 6 - The test loop (update, don't re-derive)
The tree's life doesn't end at delivery: the user runs the cheapest tests / fills the Data Request and comes back. A field run did this loop four times by hand — formalize it. On "here are the test results" (or why-tree update):
- Load the saved
why-tree-output.json — this is the one case where reading the prior tree is correct. The Phase-1 anti-contamination rule forbids reading a prior verdict when RE-DERIVING a tree from scratch; amending a live tree with new empirics is the opposite operation and reads it by design.
- Re-grade only the touched nodes — a test result upgrades HYPOTHESIS→MEASURED (with the new cite +
validation), sets contested if it disagrees with an existing node, or kills a node: role REFUTED with the killing evidence kept visible, exactly like the adversarial pass.
- Re-converge ONLY if a load-bearing node fell — if the constraint's
loadBearing node died or went contested, re-run the converge+drill step over the updated branches (2-3 agents); otherwise zero agents — just recompute the census and verdictStatus in plain code.
3b. Orphan sweep (plain code, zero agents). When any node dies or goes contested, sweep every root action, negative, and ideaFit claim whose restsOn includes it: flag each as ORPHANED in the tree and the decision doc — "this recommendation rested on a node that just fell; re-derive or retract". Never leave a recommendation (or an idea verdict) standing on a dead node. The sweep's output fields (the renderer's contract): roots[].actionOrphaned: true · negatives[].orphaned: true + orphanedBy: '<dead node id>' · ideaFit.orphaned: true + ideaFit.orphanedBy: '<dead node id>'.
- Re-render by splicing the updated JSON into the existing styled HTML's
tree-data block (the Phase-3 rule — never rebuild from the bare template), and update the decision doc's headline.
The post-hoc idea-check (same machinery, new question). On "here's my idea — would it have helped?" / why-tree idea-check <idea> against a finished tree: load the saved JSON, run the Phase-2 step-6c fit-check (+2 agents) over the existing tree, splice idea + ideaFit into the styled HTML, and append the idea-on-trial section to the decision doc. Zero re-derivation — and this is how the mode was field-discovered: the user asked the idea question only after the diagnosis was done.
Each loop costs 0-3 agents. The point: the tree stays the living map of the diagnosis — grading the empirics as they land — instead of a snapshot that drifts from reality while the human debugs it elsewhere.
Guardrails
- Token honesty first - never launch Deep without an explicit cost warning and confirmation. The gate is the skill's conscience.
- One constraint, not a list - refuse to ship five co-equal roots. Force convergence to one.
- Grade every node - no ungraded assertions; every HYPOTHESIS must name the test that would settle it.
- Refute before trust - load-bearing branches must survive an adversarial pass, and the dead branches stay visible.
- Honest census - when the decisive nodes are unmeasured, say "map, not verdict." Confident verdicts on HYPOTHESIS nodes are the worst output.
- Don't smuggle the answer into the apex - a problem framed as a missing solution biases the whole tree.
- Interaction at the edges, fail loud in the middle - the user may be asked things ONLY at the edges: the Phase-0 depth gate, the Phase-1 pre-flight data gate (+ "interview me" intake), the Phase-1.5 scout-gate routing (ship-direct vs escalate-with-receipts), and the Phase-5/6 Data Request / test-results loop. Never mid-swarm. During the run, never invent and never punt: an
in-hand gap must be computed (the deepen guard fails loud if not), and only external/experiment gaps become the Data Request — the honest "here's exactly what I'd need from you" output.
- Levers are parallel paths, not rival causes - on a target apex, the "converge to ONE" discipline applies to root causes, not to growth levers. Never refute a lever away; a weak lever is
dropped with a stated droppedReason and stays visible. A target apex shipped as a lone bottleneck with no sized portfolio is the wrong output shape.
- A number is not a fact - MEASURED says a number exists;
validation says it means what the node claims. Unvalidated (raw) caps at Mod; the constraint may never rest on a raw or contested node; two sources disagreeing in sign is a CONTESTED node with both values shown, never a "fact". "Can I compute it?" and "is the pipeline clean?" are different questions.
- The headline may not outrun the census - when the decisive node is unmeasured or unvalidated,
verdictStatus:'map' must be visible in the header itself (amber, naming the deciding test), not only in the census panel at the bottom.
- Consensus is not clear-cut - the scout gate ships a direct answer only on convergence + MEASURED-validated decisive evidence + surviving a refutation attempt. Three independent minds converging on the intuitive story is how the confidently-wrong answer ships with extra confidence; votes never gate alone.
- Recommendations are traceable - every action/negative carries
restsOn; the update loop's orphan sweep retracts or re-derives anything standing on a node that died. No recommendation may outlive its evidence.
- Judge the idea against the tree, never the tree against the idea - in Idea Audit the idea is quarantined from every scout/lens/deepen/refute prompt (and scrubbed from the frozen evidence brief); only the post-converge fit-check sees it. A swarm that knows the pitch finds the causes the pitch needs.
- An idea-kill must be graded too - "they've absorbed it as a cost of doing business" is a HYPOTHESIS about buyer behavior, not a verdict: attach kind/grade and the test that would settle it (pre-sell, budget-line check, adjacent purchases), and bound the claim with the n=1 segment fork. Killing a good idea with a confident ungraded macro-claim is the confident-verdict failure running in reverse.
- Verify system behavior empirically - don't infer it. A node claiming what a product/codebase/pipeline DOES or TRACKS (an event fires, a step is instrumented, a user sees/clicks X) is a HYPOTHESIS until you RUN the system and observe - drive the real flow + watch console/network/analytics-debug - or pull the FULL event/route inventory (
SELECT DISTINCT event_name, every page/path). A negative code-grep of one folder, or a single preconceived query, is a hypothesis - never proof of absence. Reasoning from source is the fallback, not the answer. (Field run: three "not instrumented / only-successes-logged" claims, all wrong - the leads table WAS tracked, connect-cancels + failures WERE logged.)
- The outcome→payment last hop is its own node, never an assumption folded into the constraint. "If they reach the value moment they'd convert/pay" is a testable HYPOTHESIS about behavior - grade it and cite the completers-who-actually-paid rate. A constraint that quietly assumes the last hop converts (when 1-of-3 completers and 1-of-11 value-exhausters actually paid) is a confident verdict on an unmeasured node.
- Base-rate the alarm before diagnosing it. On a small-N "X is broken / X is zero" apex, first check whether the observed number is even distinguishable from the benchmark (0 conversions / 36 signups at a 1-3% norm ≈ expected 0.4-1.1 - observing zero is a coin-flip, not a crisis). Diagnosing noise as signal wastes the whole tree; say so and widen N or the window first.
Anti-patterns
- A single-thread 5-Whys chain with a tidy bottom (no branching, no refutation = not a tree).
- Nodes asserted without an answer-kind or citation.
- "Five key root causes" with no convergence to one constraint.
- A confident recommendation resting on HYPOTHESIS-graded nodes, with no census disclosing it.
- Deleting refuted branches instead of keeping them with their killing evidence.
- Launching the deep workflow without telling the user it's token-heavy.
- Pausing the swarm to ask the user - mid-run questions can't be answered; tag the node
gap:external and route it to the Data Request instead.
- Shipping an
in-hand gap as a "cheapest test" or data-request line - if one query over data you already pulled settles it, compute it; don't outsource your own homework to the reader.
- Running the full workflow on a clear-cut problem a single agent would nail - the ablation shows that's wasted tokens; answer it directly and skip the gate.
- A flat apex → roots → constraint funnel with childless roots - the constraint branch must be a visible multi-level chain to bedrock, or it's not a tree.
- An uncapped fan-out (no
MAX_DEEPEN/MAX_REFUTE) - it balloons agent count and rate-limit-degrades the refute pass.
- A GitHub-default-looking tree - the visualization is a deliverable; run it through
frontend-design.
- Running a growth-TARGET apex as a pure constraint tree - it hands back one bottleneck and silently drops the parallel levers; a "hit N" apex needs the sized lever portfolio (+ "do they sum to N?"), not just the binding step.
- A tree with no narrative - the HTML must open with the
narrative[] memo; a raw interactive tree with no prose entry point fails the comprehension test.
- A MEASURED chip on an unaudited pipeline - bots in the denominator, a metric-definition mismatch, or a seasonal Δ shipped as a "fact". The field failure that cost 4 of 6 iterations: the tree confidently leads the wrong way until a human debunks its own "facts".
- Two sources disagreeing and the convenient one shipping as MEASURED - a sign-level divergence (−27% vs +12%) is a CONTESTED node and a finding, never a fact to build on.
- An act-ready verdict header on a
map-status tree - the census honesty must reach the headline, not hide in the bottom panel.
- Regenerating the HTML from the bare template after the design pass - splice the
tree-data block into the styled file instead; the rebuild silently drops the aesthetic layer.
- Running the full verdict machinery when the decisive sources are human-only - that's Test-plan mode: deliver the branch-map + ranked test plan, then iterate via the Phase-6 update loop.
- Guessing clear-cut instead of measuring it - when it isn't obvious whether one careful pass suffices, run the scout gate (~1/10 cost) and let convergence/divergence decide; launching the swarm on faith and skipping it on vibes are the same mistake in opposite directions.
- Shipping a scout consensus without the refute attempt - convergent intuition is not evidence (the Fish Banks scouts would have agreed on the wrong cause).
- A recommendation with no
restsOn - an action that can't name the nodes it stands on can't be retracted when they fall; that's how a killed node's build recommendation survives it.
- Refusing a solution-shaped ask instead of routing it - "evaluate my product idea" is not a smuggled-solution bug to push back on; it's Idea Audit mode (extract the presupposed problem, quarantine the idea, fit-check after converge).
- The idea leaking into the swarm - a scout/lens/deepen/refute prompt (or a frozen evidence brief) that mentions the user's idea anchors every branch toward it; the fit-check then confirms a tree built to flatter the pitch.
- An ungraded idea-kill - a "market won't pay" pronouncement with no kind/grade/test attached, killing the idea the tree was supposed to evaluate honestly.
- Generalizing an n=1 tree to a market - "this system's constraint is organizational, therefore nobody will pay" skips the segment fork; one diagnosed instance bounds the claim to systems where the same constraint holds.
- Inferring what a system does or tracks from a code-grep or a single query instead of running it - a negative grep of one folder became "not instrumented" three times in one field run (the leads table WAS tracked via a route param; connect-cancels + failures WERE logged). Drive the product and watch the events; pull the FULL event inventory before ever concluding "X isn't tracked."
- A convenience sample standing for the population - reading the 7 richest transcripts and quoting "84%" when the census was ~⅓. Census before quoting a rate, and keep the MEASURED funnel-fact ("84% never reached step Y") separate from the INFERRED cause ("because wrong-fit").
- A load-bearing metric from a single instrument with an un-named blind spot - "96% never attempted" measured off a DB row that only exists on success (blind to cancels/failures). Name what each instrument is structurally blind to (only-successes · only-completers · partial ID coverage · denominator) and triangulate across ≥2 sources.
- Diagnosing a small-N zero as a crisis - 0 conversions on 36 signups at a 1-3% norm is a coin-flip, not signal; base-rate the alarm before building a tree on it.
References & assets
references/methodology.md - Goldratt CRT, the WHY-branch logic, CLR audit, constraint location, Evaporating Cloud, negative branches.
references/answer-kinds.md - the evidence taxonomy + confidence grading rubric + citation rules (the core of the rigor).
references/workflow-template.md - the copy-paste Workflow() blueprint and the tree-JSON schema.
assets/tree-template.html - the reusable interactive-visualization scaffold.
assets/sample-tree.html - a non-confidential worked example.