Milpa Gardens
Open the planner
A bundle of fresh thyme sprigs
Photo: Evan-Amos · CC0, via Wikimedia Commons.

How this is built - a rules corpus in git, and an app that is only its front end

The real product is a versioned YAML corpus with evidence grades and an engine checked against it. The web app is a thin layer on top - the least interesting part.

The inversion

Most garden planners are an app with some data inside them. This one is a body of data with an app in front of it. That sounds like an academic distinction, and it decides everything downstream.

The product is corpus/: a set of YAML files holding 109 species, 38 guilds, 113 rules, and 35 folklore beliefs. It's built to be correct, auditable, and able to survive a complete rewrite of everything around it. If the web app were deleted tomorrow, the thing actually worth having would still be here.

Every rule states its reason, or it isn't a rule

The corpus has four rules it won't bend on. The first is the one that shapes the content the most:

No enforced rule without a named mechanism. If a rule cannot state its mechanism in one sentence without the word "helps", it is not a top-grade rule. Downgrade it or delete it.

"Helps" is the tell. It's the word that lets an unexamined claim slip through dressed up as a checked one, and banning it from that one field turns out to knock out most of the companion-planting canon in a single move.

The other three: a guild that doesn't fit your bed is shown greyed with the reason, never quietly swapped; the engine will tell you to get a soil test rather than invent a fertiliser number; and a source nobody has actually read can't be marked as verified.

Two of those four are enforced automatically, by a checker that runs on every change. The fourth one can't be - which is the whole point of the next section.

Verified means a human read the source

Every rule carries an evidence status. unverified means a language model asserted the claim from general knowledge and nobody has checked it. Moving a rule up to verified takes a real source in the rule's own notes, read by a person.

No automated process is allowed to make that call - including the one that wrote most of this code. Right now 0 rules are still sitting at unverified. That number is published, not hidden, because a corpus that can't own up to its own unchecked claims isn't really auditable.

The sources are stored as plain text, word for word, usually including the sentence that carries the claim and the date someone read it. When you open a source anywhere on this site, you're seeing what the corpus wrote down, not a tidied-up summary of it.

Demotion is a feature

Grades move both ways. A rule dropping from a confident tier to a weaker one, because the research turned out to be shakier than we assumed, is the system working exactly right - and it gets recorded, not quietly deleted.

This is why the corpus is YAML in git rather than rows in a database. Every grade change is its own commit, with the source that caused it written into the commit message. The version history is the history of what the project believed and why: you can ask when a claim was trusted, why it changed, and what somebody read that changed it.

Two engines that have to agree

The rules engine exists twice. The reference version is in Python; the app runs a TypeScript version in your browser. That's a duplication, and duplicated code drifts, so we don't leave it to good intentions: the Python side generates the answers, and the TypeScript engine is checked against them on every change. If the two ever disagree about what a rule does, the build goes red.

The same trick holds these pages honest. The site you're reading renders the corpus a second time, right alongside the app, and a test reads the app's own code and fails if the two ever describe the evidence differently.

No backend, no weather API

The app has no server. Climate data is worked out ahead of time into a static file at build time and stored in the repo like any other file. That means the planner works offline, the climate layer can be diffed like code, and the whole system's one outside dependency gets refreshed about once a decade instead of once a request.

The bits that are deliberately missing

Read it yourself

The evidence page in the app lists every rule and every belief with its grade, its reason, and its sources. This site puts the same material on pages a search engine can actually reach.

All explainers · Plan a bed