Protocol · v0.3 (2026-10-05)

The Draw Tree Protocol

A protocol for AI-native equity research. It defines what a falsifiable hypothesis tree is, how its branch weights are derived from valuation impact, how valuation is reduced to two human decisions, how a weekly judge may and may not change a verdict, and how every write is recorded as a signed, append-only version. Any MCP-compatible client — ChatGPT, Claude.ai, Claude Desktop, Claude Code, Codex, Perplexity — can drive it.

0 · Protocol vs MCP — two different layers

MCP (Model Context Protocol) is a transport: how a client lists tools, calls one, and authenticates. It knows nothing about investment research. The Draw Tree Protocol is the domain contract: what a valid tree is, how verdicts aggregate, which valuation methods are admissible, what the weekly judge may do.

LayerWhat it definesWhere it lives
MCPTransport, discovery, auth.drawtree-mcp (hosted and stdio)
Protocol kernelSchema, validator, aggregator, condition sweep, verdict-change gate, migration.drawtree_mcp/_kernel and drawtree-api/core — the same code
StateDrafts, trees, versions, valuation decisions, subscriptions.drawtree-api (FastAPI + Postgres)

Why this protocol is open

A tool that claims to bring scientific method to investment research cannot itself be a black box. The schema, the formulas, the rules the judge obeys and the client contract are all public and MIT-licensed. The kernel ships with a golden test: a real research tree from the maintainer's fleet aggregates to exactly the fleet engine's score, verdict, conviction and probabilities. If drawtree.capital disappears, committed trees remain readable against this spec.

1 · The tree

Consensus   →  What the market believes and what the price already assumes.
H-0         →  One question, one question mark, ≤120 characters, naming the
               bear outcome ("…rather than being pushed back to …").
Branches    →  3–5 necessary conditions. Each carries an impact grade derived
               from what happens to the valuation if it fails.
Leaves      →  Observable questions with a six-level reading guide, structured
               conditions on disclosed numbers, an append-only evidence ledger.
Valuation   →  Three scenarios from two human decisions (rules R1–R12).

2 · Verdicts and aggregation

VerdictScoreMeaning
✅ Validated+2The reading guide's top level has been observed.
🟢 Trending positive+1Direction supports the leaf; threshold not yet reached.
⚪ Inconclusive0No decisive reading yet. The default for a new leaf.
🟡 Trending negative−1Direction works against the leaf.
🟠 Approaching falsification−2A listed condition is close; one more reading flips it.
✗ Falsified−3A listed condition was met, on a primary or wire source.
branch score    = weighted mean of leaf scores (leaf weights, default equal)
branch verdict  = thresholds ≥1.5 / ≥0.5 / >−0.5 / >−1.5; kill at ≤−2.0,
                  or when any leaf in necessity_leaves is Falsified
branch conviction = σ( logit(0.40) + 1.5 · score )
H-0 score       = impact-weighted mean of branch scores; kill at ≤−2.0
H-0 conviction  = σ( logit(0.40) + Σ w · score/3 ), positive terms halved,
                  clamped to [0.005, 0.95]
p_bull = h0/2, p_bear = −h0/3 (verdict-based); price-implied probabilities
                  from the three targets and the current price (Max-Base)

Both probability readings are model outputs on the author's targets, reported side by side. Neither is a calibrated probability, and the protocol never produces a weighted target price.

3 · Valuation — two decisions, rules R1–R12

numerator(scenario) = street consensus × ratio(scenario)   ratio(base) = 1
multiple(scenario)  = median of the scenario's peer tier, today
target(scenario)    = numerator × multiple           (per share)
                    = (numerator × multiple + net cash) ÷ diluted shares   (EV rulers)

The author decides only two things: the bear and bull ratios to consensus (each with a one-sentence economic reason, an anchor, sourced inputs, assumptions and a cross-check), and the bear and bull peer-tier identities. The base tier is the tier whose band contains the company's own multiple. Everything else is derived by the server, and the human approves the report before anything is committed.

Tools: evaluate_valuation (free, stateless), report_two_decisions (stores and returns the report), approve_decisions (records the reply verbatim and builds the schema-2.1 document the commit attaches).

4 · Procedure — four steps, two human gates

1 RESEARCH   background brief (400–700 characters) · pricing pack · narrative
             start_draft → frame_narrative → save_narrative
2 BUILD      five questions → scenario ladder → H-0 → necessary-condition path
             frame_h0 → save_h0 → design_branches → fetch_framework_details
             → save_branches → design_leaves / save_leaves (per branch)
             preview_tree  ■ FRAMEWORK GATE — the human reads the framework
             confirm_framework
3 GATE       evaluate_valuation until no errors
             report_two_decisions  ■ TWO-DECISION GATE — the human replies
             approve_decisions(reply verbatim)
             research_phase2 → research_phase2_status → compute_scenarios
             commit_draft_tree  (validated, aggregated, signed, versioned)
4 REPORT     summarize_tree → reader report (§1 industry → company → why now;
             §2 what it sells / how it charges / where the money goes / last
             quarter; §3 consensus; §4 price chart with narrative bands)
             setup_monitoring?

The client contract (the skill) enforces the gates: nothing downstream of preview_tree or report_two_decisions is called until the human answers in the conversation. Download it from /api/skill/skill.md.

5 · Weekly monitor — what the judge may do

sweep      deterministic: overdue deadlines expire, crossed thresholds breach and latch
search     broad + targeted; every result tagged source_tier
           (primary · wire · trade · aggregator · other)
judge      sees only the evidence pool, the standing verdict, the conditions
gate       a proposed change is kept only if it
             1  cites a URL that was in this week's pool
             1b–1c  cites verifiable rows with known ids
             1d  is not an upgrade on all-challenging (or downgrade on all-supporting) rows
             2  quotes a real listed condition when entering the falsification zone
             3  is not a price-only argument
             +  Falsified needs a primary or wire source
           otherwise the standing verdict is kept and the proposal is recorded
latch      met / breached / expired conditions cannot be assessed back to not_met;
           only "superseded" with a reason releases them
freshness  first_public graded 首發 / 補課 / 未能確認
write      append-only: ledger rows, verdict_history, conditions; a signed version

A daily scheduler calls the API; weekly subscriptions run on Saturday 09:00 HKT. Rejected proposals and condition events are shown to the owner, in the email and on the tree page — nothing disappears silently.

6 · Point in time — signed, append-only versions

Every write — commit, edit, weekly judgement, price refresh, narrative refresh — appends a tree_versions row: the full payload, sha256(canonical_json), an Ed25519 signature by the operator key, and provenance (source, actor, previous version, protocol version, key_kind). Nothing is rewritten in place.

GET /v1/view/trees/by-id/{id}/versions                 history, newest first
GET /v1/view/trees/by-id/{id}/versions/{version_id}    one version, with payload
GET /v1/view/trees/by-id/{id}/state_at?at=ISO          the tree as held at or before a cutoff
GET /v1/view/trees/by-id/{id}/versions/diff?from_version=&to_version=
GET /v1/server_pubkey                                  public key and key_kind

state_at is the only read a backtest or a dispute may use. A version signed by a development key is marked key_kind: dev and is not an attestation.

7 · The MCP tool surface

Kernel · valuation gate · point in time (free)
  • validate_tree / aggregate_tree
  • migrate_tree / sweep_conditions
  • evaluate_valuation
  • report_two_decisions / approve_decisions
  • read_valuation_draft
  • read_tree_versions / read_tree_version
  • read_tree_state_at / diff_tree_versions
  • commit_tree / read_tree / read_history
  • suggest_framework
Draft flow · view mode (hosted server)
  • start_draft → frame_* / save_* → preview_tree
  • confirm_framework (Phase 2 bundle)
  • research_phase2 / research_phase2_status
  • compute_scenarios / commit_draft_tree
  • summarize_tree / read_committed_report
  • my_workspace / list_my_drafts / list_my_trees
  • read_branch / propose_edit / apply_edit
  • setup_monitoring / pause / resume / cancel
  • search / fetch (ChatGPT-compat)

The stdio server ships the kernel, the valuation gate, publish and point-in-time reads (20 tools). The hosted server adds the draft flow and view mode. Read-only and kernel tools never charge; the client never mentions credits — the balance is at /account.

8 · Architecture

┌──────────────┐  MCP (stdio / Streamable HTTP)  ┌──────────────────────────┐
│  AI client   │ ───────────────────────────────▶ │  drawtree-mcp (Render)   │
│ ChatGPT      │                                  │  kernel v0.3 · OAuth     │
│ Claude.ai    │                                  └────────────┬─────────────┘
│ Claude Code  │                                               │ REST, Bearer dt_…
│ Codex · …    │                                               ▼
└──────────────┘                                  ┌──────────────────────────┐
                                                  │  drawtree-api (Render)   │
                                                  │  core/ = same kernel     │
                                                  │  valuation R1–R12        │
                                                  │  weekly judge + gate     │
                                                  │  Ed25519 · tree_versions │
                                                  │  Postgres (Neon)         │
                                                  └──────┬─────────────┬─────┘
                                                         ▼             ▼
                                        ┌──────────────────┐  ┌──────────────────┐
                                        │ drawtree-dashboard│  │ daily scheduler  │
                                        │ (Vercel) reads    │  │ → admin_run_cron │
                                        │ the same API      │  │ (Saturday judge) │
                                        └──────────────────┘  └──────────────────┘

9 · What is not in the protocol