# PhytoEngine: The Long Horizon

> A speculative north-star document. This is *not* the roadmap (see `next-steps.md`
> for what's actually being built). It's the horizon that roadmap points at, so that
> near-term decisions can be checked against where the thing could go.
>
> **Revision, 2026-07-10.** The first draft of this document described a destination
> but never said what force carries us there. It listed capabilities — parametric
> kernel, provenance, time axis, learned model — and no measurement. "More real" was
> not a gradient anything could climb. This revision names the missing piece: the
> **residual**, and the ratchet it turns. Everything else here is the original
> argument, re-derived around it.
>
> **Revision, 2026-07-18.** The prior draft framed the residual's referent as
> *field-measured biological ground truth* — a species' actual bark thickness, its
> actual bloom date — with biologists and ecologists as the eventual contributors.
> That framing implied a scientific-institution ambition this project is not pursuing
> and is years from earning. PhytoEngine is a video-game plant pipeline: assets for
> fantasy worlds and photoreal ones alike. This revision re-derives the residual around
> a **visual referent** instead — a photograph, a piece of concept art, a measured 3D
> scan, an art director's approved reference sheet — so the same ratchet (a number that
> can go down) drives fidelity without claiming to be a research institution. GBIF
> corroboration remains working code (moved to `api/src/Research/` — see
> `next-steps.md`) but is no longer part of the core narrative.

## Where it starts

Today PhytoEngine is a catalog and pipeline: Meshy- and Blender-procedural trees
pushed through a gltf-transform pipeline into LOD'd GLBs, a MySQL catalog behind a
PHP API, and a deterministic `forest-recipe.js` layer that turns seed+biome+size into
placements a three.js client renders. That's the seed. This document describes the
tree.

## What it becomes

PhytoEngine stops being a folder of tree meshes and becomes **the canonical
computable model of plant life** — the thing you query when you need a plant, any
plant, at any fidelity, at any moment of its life, in any context. Not a static asset
store but a *generative substrate*: you don't download a birch, you request
"Betula papyrifera, 34 years old, growing on the north slope of a moraine at 46°N,
third week of a dry September, moderately shaded by conspecifics, at 2,000 triangles"
and it grows one for you — deterministic, reproducible, and correct at whatever level
of correctness you asked for.

The architecture today is secretly already this shape. The catalog with fallback
chains becomes a **fidelity ladder**: the same semantic plant resolves to an
80-tri N64-style billboard puppet, a game-ready instanced mesh, a film-quality hero
asset, or a physiologically simulated organism with modeled xylem, depending on what
the requester can afford. The `assetPlan()` gap report becomes the demand signal that
tells the growth engine what to synthesize next. The seed+biome determinism becomes
the guarantee that a scene renders identically on a phone in 2029 and in a research
cluster in 2041.

---

# The residual: the product, and the ratchet

*This section is the centre of the document. The rest follows from it.*

## The question the first draft could not answer

*What makes each generation of tree-recipe feel more real than the last?*

Nothing in a capability roadmap answers this. A learned model is not more real than a
procedural one; it is only more *general*. A provenance graph is not more real; it is
only more *honest*. Time as an axis is not more real; it is only *more*. You can build
every phase of this document and end up with a beautiful, unfalsifiable tree — which
is exactly what everyone else has already built.

Realism is not a capability. It is a **measured distance to a referent, decreasing.**

## The definition

Every species record carries a **residual**: the disagreement between what we grow and
the best reference we have for what that species — real or invented — should actually
look like.

It is not one number. It is a vector over the things a reference can show — canopy
silhouette against a photo or a concept painting, bark texture at walk-distance, leaf
density and color against reference art, proportions against an approved reference
sheet, crown shape against a measured 3D scan. Each component has a value, a
confidence, and a provenance (which photo, which artist, which scan). Where no
reference exists yet, the residual is not zero — it is **unknown**, and that is a
different and more useful thing than zero.

The product is not the mesh. The mesh is cache; this document already says so
("generated artifacts are cached evaluations, not primary truth"). The product is:

> **A species record with a residual — public, versioned, citable — and a history
> showing that residual going down.**

## Species without a referent — fiction is first-class

A residual is a distance to a referent. **Some species have no referent, and that is not
a defect.** `moon-lantern-tree` has no field measurements because it does not grow
anywhere. Neither do `whimsy-oak`, `spiral-pine`, `toadstool-tree`, or
`willow-of-whispers`, and the storybook biome is one of the seven shipped.

So the residual has **three** states, not two:

| state | meaning | example |
|---|---|---|
| **measured** | a reference exists; the residual is a number, and it should fall | `birch` canopy silhouette against reference photography |
| **unknown** | the species is real, no reference has been gathered yet | `tamarack` — grown from a text description, zero reference photos |
| **not applicable** | the species has no referent by construction | `moon-lantern-tree` |

`unknown` is a debt. `not applicable` is not. Collapsing them — treating a storybook tree
as an unmeasured real one, or worse, excluding it from the catalog because it cannot be
verified — would be a category error, and it would delete the biome PhytoEngine ships
today.

The invented species are held to a different standard, and it is a real one: **internal
coherence with the botany the engine already knows.** A moon-lantern-tree still obeys
allometry, phyllotaxis, tropism, crown competition and wind stiffness. It is a plausible
plant that happens not to be an actual one. The realism the residual measures is what
makes the fiction *convincing* — the fantasy species are grown by the same kernel, and
they inherit every unit of realism it earns.

This is the same relationship a language model has to fiction: the poem is not a failed
fact. It is a different use of the same machinery, and it is only good because the
machinery knows what the world is actually like.

**The goal, stated exactly:** the most realistic living trees, improving as fast as the
data they are given — and, from the same kernel, unreal trees that are convincing
*because* of it.

## Why this is the ratchet

A residual makes fidelity a *gradient*, and a gradient is the only thing a system can
climb without a human deciding, each time, what "better" meant.

- It tells the growth engine **what to fix**: the largest confident component.
- It tells the build queue **what to build**: not the most numerous asset, but the one
  where wrongness meets exposure (see below).
- It tells a learned model **what to train against**: a loss, not a vibe.
- It tells a contributor **what their measurement bought**: the component it moved.
- It tells a subscriber **what they are getting**: not "a tree" but "a tree that is
  this far from the real thing, and here is who says so."

Every phase in the second half of this document exists to drive some component of the
residual down, or to widen the set of components that *can* be measured. That is the
only test a phase has to pass to belong here.

## Open question: the metric residual is not the whole of realism

A numeric residual measures allometry — heights, diameters, angles, bloom dates. It does
**not** measure whether a tree *looks like* its species.

The evidence is this repo's own history. The bead-curtain tamarack rosettes, the
pagoda-plate branches, the "still looks a bit christmas tree" Norway spruce, and — on
2026-07-10, eight minutes after this section's argument was first made — a freshly grown
`oak/mature` that is unmistakably an **acacia**: thin bole, high fork, flat umbrella
crown, where a real *Quercus* has a massive short trunk, a low heavy fork, and a deep
rounded crown running two-thirds of the tree's height. **Every one of those defects was
found by rendering, not by reasoning, and not one of them would move a metric residual by
a millimetre.** A height–DBH fit would have scored that oak perfectly and shipped it.

So there are plausibly **two** residuals: the **metric** one (allometry versus field data)
and a **perceptual** one (does the silhouette agree with reference photography). The
second is the one Matt's eye has been computing, unpaid, for the entire project.

How to make the perceptual residual rigorous is genuinely unsolved. Candidates, none
sufficient: silhouette IoU against `docs/reference/` photography; a learned
real-versus-generated classifier; a human survey. Each has an obvious failure mode.

**This is an open question, recorded rather than answered, and it does not block the
evidence schema.** But if we build only the metric residual, we will optimise a number
while the trees get worse, and we will not notice.

## Why this is the moat

SpeedTree cannot be wrong. Quixel cannot be wrong. A Meshy generation cannot be wrong.
None of them has a referent — there is no fact of the matter about whether their birch
is a good birch, only whether an art director liked it. They are unfalsifiable, and
unfalsifiable is a synonym for *unimprovable except by taste*.

**PhytoEngine is the only tree library that can be wrong.** That is not a weakness to
be engineered away; it is the entire asset. A number that can go down is worth more
than a picture that cannot be checked, because a number that can go down attracts
people whose job is to make numbers go down.

This is also the honest answer to *"why would anyone subscribe for assets that already
exist?"* Because the tree arrives **accountable**: it knows what biome it belongs to,
what it looks like at 34 years, what it costs at 2,000 triangles, how far it is from
its reference, and where that reference came from. Nobody else ships that, and no
amount of raw model intelligence conjures it (see "the honest question", below).

## The demand signal is residual × exposure

The first draft promised that `assetPlan()`'s gap report "becomes the demand signal for
a generative model." As built, that signal ranks by **instance count**, and instance
count is demonstrably the wrong objective.

The proof arrived from a consumer. In the `huffman-prairie` biome, `honey-locust/old`
is the lone marker tree Wilbur Wright turned around to close the first complete circle
in 1904. It has a demand of **1** and a priority of **low**. `american-elm/mature` has
a demand of 510 and outranks it. The scene exists *because of* the marker tree.
ageOfFlying had to hand-author a build order to override us, and named the flaw
exactly: *"Demand-based priority cannot see this."*

Ranked by instance count, a generative model learns to make more of whatever there is
already a lot of. The correct objective is:

> **residual × exposure** — how wrong the asset is, times how hard anyone looks at it.

A badly-wrong tree at the wingtip at three metres outranks a slightly-wrong tree that
appears 510 times at eighty. Exposure is recoverable from the recipe (`loneSpecies` is
already a declaration that *this one matters*); residual is recoverable from the
evidence. Neither is recoverable from a count.

## Evidence, not values

The residual only exists if the referent exists. So:

> **Nothing in the catalog stores a measured quantity as a value. It stores
> *evidence*, and the value is a view over the evidence.**

`species.mature_height = 22` is an unsourced assertion, indistinguishable a year later
from a measurement. `evidence(species, 'mature_height', 22, source, confidence, n)` is
a claim someone made, that a better claim can supersede, and whose disagreement with
the grown geometry *is* a component of the residual.

The first row for a new species will read `source: "language model, unverified"`,
`confidence: low`. That is correct and useful. It is honest about what it is, it is
addressable, and it is the exact shape the row will still have later, when a real
reference photo or a measured scan replaces it with `source: photo:<url>`,
`confidence: measured`. Nobody will need a new system. They will supply a better row
for a field that already knew it was uncertain.

**This is cheap now and cannot be retrofitted.** A value that was never evidence has
lost, permanently, the information about where it came from.

## What a contributor gets

Not a mesh. They contribute *a reference that moves a residual* — a photo, a concept
painting, a measured scan, a corrected reference sheet — and in return their name is
credited on every frame of every film and every forest in every game that used that
species. Provenance flows downstream, all the way to the pixel. That is the incentive
loop that makes them show up, and it is why the reference library is worth building
rather than just a folder of screenshots.

---

# Who else is in this field

Being alone in a field usually means being in the wrong field. PhytoEngine is not
alone; it sits in a **gap the mature asset stack has never closed.**

## The asset stack — beautiful, unfalsifiable

- **SpeedTree** — the industry standard for film and games. Parametric, artist-driven,
  excellent. Sold as an authoring tool, per seat, to studios. Makes no botanical claim
  and offers no referent; its trees are *art-directed*, not *measured*.
- **Quixel Megascans** — photogrammetry. Genuinely real, and therefore genuinely
  frozen: a captured specimen has one age, one season, one moment, no parameters.
- **Xfrog, PlantFactory, The Grove 3D** — parametric plant libraries and, in The
  Grove's case, an actual growth simulation. The Grove is the closest thing to "time as
  an axis" shipping today, and it is a Blender artist tool, not an API.
- **Meshy, Tripo, and the genAI 3D cohort** — instant, plausible, and referentless.
  Structurally incapable of being wrong.

Every one of these is an **authoring tool sold to a studio**. None is a queryable
authority. This is the direct reason a solo developer looking for decent trees finds
either a per-seat DCC licence aimed at a 40-person art department, or a free mesh with
no semantics at all. The middle is empty.

## The gap

**Every one of the asset-stack tools above is unfalsifiable and unaccountable.** None
of them ships a citation, a confidence, or a number that can go down. SpeedTree has no
references. Quixel's scan is frozen the day it was captured. A Meshy generation cannot
say what it was supposed to look like, let alone how close it got.

PhytoEngine's claim is the bridge, and the bridge *is the residual*: the number that
says the thing you are rendering agrees, to a stated degree, with the reference it was
built against — fantasy or photoreal, it doesn't matter which, as long as the
reference is named. Not a better SpeedTree — a different category, competing on an
axis SpeedTree does not have a coordinate on.

The business shape differs accordingly. SpeedTree sells an authoring tool to studios.
PhytoEngine is a **queried authority** that engines call: `import trees`. That is the
one-line summary of the whole project, and the resolver behind it already exists — it
is `assetPlan()`, currently trapped client-side in `forest-recipe.js`, reporting its
gaps inward to a build queue instead of outward to the caller.

---

## The fidelity ladder — one plant, every resolution

The unifying idea: **N64-detail and photorealistic-biome are the same object at two
zoom levels of the same underlying model**, not two different products.

- **Low rung** — stylized, cheap, expressive. Hundred-triangle plants with hand-tuned
  charm. Today's game path, matured.
- **Middle rung** — game-ready, animated, believably arranged. Instanced forests
  with per-branch wind, dynamic LOD, seasonal color, believable spacing from crown
  competition. Where Villiagers lives.
- **High rung** — photoreal, physically-based, indistinguishable from its reference.
  Leaf venation, species-correct bark rugosity, phyllotaxis obeying the real divergence
  angle, canopy architecture matching reference photography. For film, or a hero shot.
- **Top rung** — the plant as a *process*, not a shape. Not "what does it look like"
  but "how does it behave over a season or a lifetime": drought thinning a canopy, a
  branch shed after storms, color and density changing across an in-game year.
  Geometry becomes an *output* of the simulation rather than a stored thing.

You climb the ladder continuously. The N64 birch and the hero-asset birch descend
from the same genotype+environment description; they differ only in how much of the
model you chose to evaluate.

**Where we currently violate this.** `grow_birch.py` and `grow_birch-leafy.py` are two
hand-written scripts, stitched back together by a `LEAFY_OF` / `STYLIZED_OF` lookup
table. The ladder, as implemented, *is* a fork of the definition — precisely what the
invariants below forbid. Phase 1 exists to unfork it. Naming this here so that no
future surface (an admin panel, a pricing tier, an API parameter) paves the fork by
modelling rungs as *versions you make and store* rather than *evaluations you request*.

## From JS library to a learned generative model

Today the "brain" is procedural — `grow_spruce.py` is a clever human-written recipe.
Over years the hand-written recipes become **training data and physical priors for a
learned model of plant morphology**. Instead of one Python script per species, a model
that has internalized how *plants in general* grow — branching, tropism, allometry,
senescence — conditioned on a species, an environment, and a moment in time to emit a
plant. New species stop requiring a new script; they require a description and a few
reference specimens.

The residual is what makes this trainable at all: it is the loss. Without it, "a
learned model of plant morphology" means a model that produces plausible trees, which
is a solved and worthless problem.

That's the "holodeck would check it" state: when any downstream system — a game
engine, a film pipeline, a VR world, a simulator — needs to place a plant in a scene,
PhytoEngine is the authority it consults for *what would actually grow here and what it
would look like doing so*. The plant equivalent of a physics engine: nobody ships their
own gravity, and nobody should ship their own botany.

## The living reference library — where art enters

The piece that turns a tool into an institution: **artists and photographers publish
into it**. Reference photography, approved concept art, digitized specimen photos,
player-submitted reference sheets — these become contributions to a shared, versioned,
citable reference library, the same way a well-run studio keeps a style bible instead
of an unstructured mood board. Each contribution improves fidelity for that clade or
biome, and each is traceable: a rendered plant can cite the references that shaped it.
Today's `source` enum is the primitive ancestor — a provenance field that eventually
says not "meshy" or "procedural" but "grown from model v9, constrained by [three
reference images]."

That closes the loop that makes the accountability claim real: an art director can
trust the simulated biome *because* it's built from cited, inspectable,
disagreement-tracked reference — and when the render and the reference diverge, that
divergence is itself useful feedback worth recording. **The divergence has a name. It
is the residual.**

## Time as a first-class axis — growth, decay, seasons

Right now a plant is a static GLB. In the mature system **time is a dimension you
scrub**. The same organism renders at age 2, 34, and 300; you watch a fallen log
(already generated as snags and fallen-logs) actually rot — colonized, softened,
reclaimed — on a timelapse slider, or a canopy leaf out and senesce across a modeled
year. Decay and growth aren't separate assets; they're the trajectory of one simulated
life. This is what makes it a *study* instrument rather than a diorama: run a stand
forward fifty years and ask what it becomes.

## Planning and previewing biomes that don't exist yet

The forest-recipe layer's descendants let you **compose and simulate biomes that don't
exist yet** — a terraformed valley, a speculative fantasy biome, an alien treeline —
and let it run to see whether it coheres: does the understory survive the canopy, does
the spacing read as a place rather than a scatter, where does the palette fall apart.
A game designer paints a believable alien-but-plausible forest and previews it before
committing art budget; a worldbuilder checks whether a fantasy biome holds together at
scale. Same engine, different requester.

## The honest question: still useful to a vastly smarter consumer?

Would this stay a time-saver against a model 100× smarter and faster? Yes — and the
reason is *not* the reasoning.

A far smarter model doesn't need help *thinking about* how a birch grows. What it can't
conjure from raw intelligence:

1. **A reference it didn't see.** No intelligence tells you what a specific reference
   photo actually shows, or what an art director actually approved for this species.
   That's *a fact of your project*, and it lives in the reference library. PhytoEngine
   is a moat of curated, provenanced reference data — the one thing intelligence can't
   substitute.

2. **Determinism and shared reference.** A smart model regenerating a forest from
   scratch is *plausible* but never *the same* and never *citable*. PhytoEngine gives a
   fixed, addressable, reproducible answer two parties (or two runs years apart) agree
   on. Science and collaborative production both need a fixed point, not a fresh
   hallucination.

3. **Amortized computation.** Being 100× faster still makes it wasteful to re-derive a
   canopy from physics every frame for every viewer. A cached, LOD-laddered, pre-solved
   substrate is *strictly* cheaper than regeneration no matter how fast the regenerator
   is.

4. **The verification anchor.** A smarter model's confident output still needs checking
   against reality. PhytoEngine is where "reality" is stored — the thing you diff a
   generated plant against to know it's right. **This is the residual, and it is the
   first three reasons in one.**

The role shifts. Today it saves the labor of modeling trees. At the horizon it saves
*any* intelligence the thing intelligence can't self-supply: **verified measurement,
reproducible reference, and amortized truth.** The smarter the consumer, the more
valuable a trustworthy, citable, deterministic source of ground truth becomes — because
the consumer's own cleverness is no longer the bottleneck; *knowing what's actually true
of real plants* is.

## The through-line

Little of this requires abandoning what's there:

| Today | Horizon |
|---|---|
| `source` provenance enum | Citable, versioned knowledge base |
| Catalog fallback chains | Continuous fidelity ladder |
| Seed determinism | Reproducible scientific reference |
| `assetPlan()` gap report | `GET /api/v1/resolve` — the public API, and the demand signal |
| A substitution in a gap report | A **residual**, reported to the caller |
| Static GLB | A point sampled from a plant's whole timeline |
| `forest-recipe.js` | Biome simulator |
| A typed-in `mature_height` | An evidence row with a source and an uncertainty |

PhytoEngine's endgame isn't a different project — it's *this* project, with time added
as an axis, a reference library added as contributors, learning added as the engine,
and accountability added as the product. The OpenOcean for plant life: the place
everything that needs a plant — a game, a film, a VR world — goes to ask what it
should look like.

---

# Architectural evolution — phases

Each phase is a coherent architecture that delivers value on its own and leaves the
system usable, not a half-built girder waiting on the next phase. The ordering follows
dependency, not ambition: earlier phases are the substrate later ones require. Rough
horizons are directional, not commitments.

**Every phase now carries a residual clause**: what component of the residual it drives
down, or what it makes newly measurable. A phase that cannot answer that does not
belong in this document.

## Phase 0 — Catalog & pipeline *(where we are, ~2026)*

**Shape.** Asset store + deterministic placement. GLBs from Meshy/Blender through
gltf-transform; MySQL catalog behind a PHP API; `forest-recipe.js` maps
seed+biome+size → placements; three.js reference client.

**What already points forward.** `source` enum (→ provenance), fallback chains
(→ fidelity ladder), `assetPlan()` gaps (→ demand signal), seed determinism
(→ reproducible reference).

**Residual clause.** None. Nothing is measured; the residual is *unknown everywhere*,
which is the correct reading of Phase 0 and the reason Phase 2 cannot wait for Phase 4.

**Exit criterion.** ~~A downstream game (Villiagers) consumes the catalog in production
with dynamic LOD.~~ **Met, 2026-07-05, by a different consumer than predicted:**
armAndFire consumes the live API for every landscape asset with zero bundled files.
A second consumer (ageOfFlying) now exerts genuine demand pull — it filed proposals
through a scoped requester key, authored a biome, and reported two engine defects
upstream. Villiagers remains a prototype. **Phase 0 is exited.** The lesson worth
carrying: the pull came from a direction the roadmap did not name.

## Phase 1 — Parametric species & the fidelity ladder made explicit *(~1–2 yrs)*

Turn per-species Blender scripts into a **single parametric growth kernel** driven by a
species-parameter record (allometry constants, branching angles, phyllotaxis, seasonal
palette). A species becomes *data*, not a new script.

- Formalize the fidelity ladder as an API dimension: every request carries a target
  (triangle budget / rung), and one plant definition resolves to any rung.
- Continuous **age** as an input the caller may ask for — but **age is derived, not
  indexed**. *Clarified 2026-07-10: the promise stands; the path to it changes.* A
  reference photo shows a tree's *size*, never its exact age. So the kernel is indexed
  on **size** (trunk diameter): `height ~ f(diameter)` is the dense, fittable relation.
  Age reaches it through a weaker, approximate growth-rate curve that carries real
  uncertainty and must report it. Asking for "a 34-year-old jack pine" is a *harder*
  question than asking for "a 20 cm jack pine," and the system should answer both,
  honestly. **Stages remain the public vocabulary** — a request asks for `mature`, and
  a stage resolves to a diameter band within which height range drives variation. See
  `evidence-schema.md` §1.
- Catalog schema grows a `species_params` table; GLBs become *cached evaluations* of
  `(species, age, env, fidelity, seed)` rather than authored primary artifacts.
- **Unfork the ladder.** `grow_birch.py` + `grow_birch-leafy.py` collapse into one
  definition evaluated at two rungs. `LEAFY_OF` / `STYLIZED_OF` disappear.

**Residual clause.** Makes the residual *expressible*: a parameter record is the thing
a measurement can disagree with. You cannot have a residual against a Python script.

**Dependency it creates.** A parameter space that a learned model can later occupy.
**Exit criterion.** A new species ships by authoring a parameter record + a few
reference images, no new Python.

## Phase 2 — Provenance & the knowledge base *(~2–3 yrs)*

Promote `source` from an enum to a **provenance graph**. Every plant, and every
parameter that shaped it, cites its evidence.

- `evidence` store: measurements, curves, specimens, each with a citation (DOI /
  dataset id) and an uncertainty. **Values become views over evidence.**
- Species parameters become *fitted to* evidence, with the fit recorded — a plant can
  answer "why do you look like this?"
- The fit's error **is the residual**, computed rather than asserted, and published on
  the species record.
- Contribution API + review workflow so external contributors — reference artists,
  photographers, players — can submit evidence. Versioned and diffable; disagreements
  are first-class, not overwritten.

**Residual clause.** This phase *creates* the residual. It is therefore the load-bearing
phase of the entire document, and the cheapest part of it — one table and a resolver —
should land in Phase 0.5, as the back end of the species-ingest flow, long before the
review workflow exists. The first evidence row may cite a language model. It must still
be a row.

**Dependency it creates.** The ground-truth moat and the citability that makes the
science use case legitimate.
**Exit criterion.** An outside researcher's dataset changes a rendered species, with
the change traceable to their submission — and the species' published residual drops.

## Phase 3 — Time as an axis: growth, decay, phenology *(~3–4 yrs)*

Make `(species, env, seed)` yield a **trajectory**, not a snapshot. Age stops being a
lookup and becomes integration of a growth process; the same machinery run past
maturity gives senescence and decay.

- Growth/decay simulation kernel: carbon allocation, shading, branch shedding,
  rot/colonization for deadwood.
- Phenology tied to environmental drivers (degree-days, water) so seasons and specific
  years render correctly.
- Client gains a **time scrubber**: scrub age, timelapse a year, watch a log rot.

**Residual clause.** Opens the entire *time-indexed* half of the evidence base —
growth curves, ring series, bloom dates — to comparison. Most published forestry
measurement is a function of age, and today we cannot even be wrong about it.

**Dependency it creates.** A behavioral (not just morphological) model — the substrate
for biome simulation.
**Exit criterion.** A stand renders continuously from seedling to snag from one
definition.

## Phase 4 — Learned generative morphology *(~4–6 yrs)*

Replace the hand-written kernel's interior with a **learned model of plant morphology**,
trained on the parametric kernel's outputs + the evidence base, conditioned on
species+environment+time.

- Model emits geometry (or the parameters that generate it) at any rung; the procedural
  kernel becomes the physical-prior regularizer and the verification oracle.
- Generalizes across clades: a sparsely-measured species is inferred from relatives +
  its few measurements.
- Determinism preserved via seed + pinned model version, so reproducibility survives
  the shift from procedural to learned.

**Residual clause.** The residual is the loss function. This phase is not possible
before Phase 2 in any meaningful sense — a generative model trained without a referent
produces plausible trees, which is a solved and commercially worthless problem, and is
what the rest of the industry already sells.

**Dependency it creates.** Coverage and realism no hand-authored pipeline can reach —
the "holodeck checks it" tier.
**Exit criterion.** A never-scripted species renders defensibly from description +
reference alone, and diffs acceptably against held-out field data — *acceptably* now
having a definition: a residual below the measured between-site variance of the species.

## Phase 5 — Biome simulation & world planning *(~6–8 yrs)*

Lift the single-plant trajectory to the **stand and biome**: many plants competing for
light, water, and space over decades. `forest-recipe.js` grows up into a succession
simulator.

- Inter-plant dynamics: competition, mortality, recruitment, succession.
- Scenario tooling: design a planting or an environmental shift, run decades forward,
  inspect where it stabilizes or collapses.
- Validation against reference imagery of real stands — divergences flagged as
  feedback fed back to Phase 2.

**Residual clause.** Extends the residual from the plant to the **stand**: canopy
coverage, stem density, species composition over succession, checked against
reference photography of comparable real or fantasy stands.

**Exit criterion.** A game designer authors a believable novel biome — fantasy or
photoreal — from the same tool, and can show it holds together decades forward.

## Phase 6 — The reference substrate ("OpenOcean") *(~8+ yrs)*

PhytoEngine becomes the **queried authority** other systems consult for plant life —
the plant physics engine.

- Stable public query API across all rungs; engines/film/VR pipelines integrate rather
  than roll their own botany.
- Federated, governed reference library: studios and contributors submit and cite;
  provenance and versioning are the trust backbone.
- Serves the two ends of the same object equally well: an N64 puppet for a hobby game
  and a hero-quality photoreal asset a film's VFX team relies on — both from one
  definition, one citation trail, one deterministic seed.

**Residual clause.** The residual is now the public contract. Every response carries
one. Consumers choose fidelity by choosing a residual they can live with, and pay
accordingly.

**Exit criterion.** Independent third parties depend on PhytoEngine as ground truth and
publish results built on it.

## Cross-cutting invariants (hold in every phase)

- **Determinism.** `(inputs, seed, pinned-version)` always reproduces byte-for-byte.
  Never sacrificed for realism — it's the product. *There is currently no pinned
  version; `forest-recipe.js` exports no version constant, and a stale CDN copy has
  already served two clients different forests for the same seed. The invariant is
  aspirational until `RECIPE_VERSION` exists.*
- **Falsifiability.** Every claim about a plant is checkable against evidence, or
  explicitly marked as unmeasured. "Unknown" is a legitimate and useful value; a
  confidently wrong value is not. *Species with no referent (storybook, invented) carry
  `residual: not applicable` — never `unknown` — and are judged instead on coherence
  with the botany the kernel already enforces.*
- **Evidence, not values.** No measured quantity is stored as a bare value. Values are
  views over sourced, uncertain evidence rows. Retrofitting this is impossible.
- **Fidelity independence.** Any plant resolvable at any rung; rung is a request
  parameter, never a fork of the definition. *(Violated today by the
  stylized/leafy script pair. Phase 1 repays it.)*
- **Provenance forward-compat.** Nothing enters the catalog without a traceable origin,
  even in Phase 0 (`source`), so the graph never has to be retrofitted.
- **Backward-runnable.** Every phase keeps the previous phase's requests valid;
  yesterday's Villiagers scene still renders.
- **Amortization.** Generated artifacts are cached evaluations, not primary truth, so
  cheaper reuse always beats regeneration regardless of how fast the generator gets.
  *A corollary that decides real cases: an artifact with no parameters behind it — a
  Meshy mesh, a photogrammetry scan — can never be a cached evaluation. Such artifacts
  belong in the reference lane, never the production lane.*
