BEST
TREE

Photograph a tree. We identify the species, score the find by rarity, and a best man delivers a wedding roast in which the tree is the groom — and never once admits it.

0
Score
0
Species
0
Finds

The groom is waiting. Point your camera at any tree and we'll find out who he really is — then say a few words.

§ 01

The Capture

Every find begins with a single photo of a leaf, a branch, or a strip of bark. The client posts it to /api/identify, which runs it through a plant-ID adapter and returns a species, a Latin name, and a confidence. Identification and roast are two separate server calls behind one tap — so a blurry, low-confidence shot can be turned away before a single word of speech is spent on it.

§ 02

The Rarity Ladder

Four tiers: Common (10), Notable (25), Hidden Gem (60), Rare Find (150). The rarity source is a hand-curated table — defensible and immune to the observation bias that makes a common urban tree read as “rare” just because nobody logs it. It's seeded for the Saskatchewan prairie — aspen and Manitoba maple are everywhere; a tamarack out of its bog is a genuine catch — and grows from there. Unknown species default to Notable until classified.

§ 03

The Roast

The speech is generated live by Claude, server-side, for whatever species came back — never pre-written. The best man describes real botanical facts (growth speed, wood, litter habit, allergens, invasiveness) as if they were the groom's human virtues and flaws, and never lets on that the groom is a tree. Two affectionate jabs, a “remember the time,” and a sincere toast. A rare find earns one dry line of credit — never a participation trophy.

§ 04

The Scoring

All scoring is server-side; the client never computes or submits points. First find of a species pays full tier value; a repeat pays a quarter. A photo under 60% confidence holds its points and its speech and asks for a clearer shot. Find five distinct species in one calendar day and a variety bonus of fifteen lands on the find that crosses the line. Score and Guest Book persist in Postgres — no reset on refresh.

§ 05

The Stack

Next.js and React on top of Postgres and Prisma. The plant-ID provider sits behind one adapter interface — Pl@ntNet, Plant.id, or an offline mock — chosen by environment, so a route never touches a provider SDK directly. The Anthropic key stays on the server; the roast prompt never reaches the browser. No port literal lives in any committed file: the Node process binds whatever the process manager assigns, and Apache reaches it by name.

§ 06

The Open Decisions

The spec left a few calls to make. Next API routes over a split backend — one runtime, not two. The hand-curated rarity table as the primary source, with live occurrence counts treated only as optional enrichment. And the ID provider chosen at config time: Pl@ntNet's free non-commercial tier, Plant.id's paid commercial tier, or the mock for a keyless run — the choice that decides whether this can ever be public-facing.

There's a groom on every street. Tell someone.