Terra
A Field Console for a Smallholding That Kept Failing Silently
A solution architecture and working prototype for managing a rehabilitating smallholding — 53 plants, two irrigation controllers, and a decade of accumulated guesses. Every failure on the property had the same shape: two kinds of truth drifting apart with nothing comparing them. Terra is built around reconciling them, and around rendering 'I don't know' as a first-class answer instead of a plausible default.


The Problem
An emitter labelled 2 GPH was actually delivering 0.65. Sixteen trees were under-watered for an unknown length of time, and nothing in any tool anyone uses would have caught it, because the label and the reality were never compared. Meanwhile a chlorotic lemon had been treated repeatedly without anyone ever establishing whether the diagnosis was right — apply chelated iron, feel productive, and three seasons later the plant is still yellow.
Research & Discovery
The weekly capture flow is shaped by the actual constraint: one person, one hand, twenty minutes, no signal. The route is generated by physical position rather than plant ID so there's one circuit and no backtracking, and photos carry a ghost overlay of the previous image so framing matches
Health is assessed as component sliders with prompts rather than one vague number, and trend is surfaced more prominently than value — a plant at 60 and rising is fine; a plant at 78 that was 90 last month is the one to look at
Every scheduled task carries its rationale, because 'prune the apricot in late summer' is forgettable and 'prune the apricot in late summer because Eutypa enters through wet-weather wounds' is not. Two rules that are destructive rather than merely suboptimal get blocking treatment
Strategy
Three Truths
Intent, Configuration, and Reality drift apart silently. Three pairs, three reconcilers — that's the entire architecture.
Anchored Numbers
Every derived figure traces to an independently-stated requirement. A number with no anchor cannot be checked, and it will drift.
Uncertainty Propagates
'I don't know' is a first-class state. A plausible default is worse than a blank, because a blank prompts investigation.
Cost of Delay
Attention ranked by severity × time sensitivity × irreversibility ÷ effort — which surfaces the five-minute job that prevents a dead tree.
Key Decisions
Made the drift warning obstructive rather than informative. Above 30% deviation it is not dismissable — you can act or you can revert, but you cannot acknowledge and move on. The original failure was invisible for an unknown period, so making it visible isn't enough
Made the follow-up date a mandatory field on every treatment. You cannot log an intervention without committing to check whether it worked, and the system generates that task and asks a specific question. Without it the loop never closes
Treated map coordinates as an editable working guess rather than a survey, because they were hand-placed from a verbal description. Eight plant identifications are recorded as unknown rather than guessed at
Kept the delivery calculator as pure functions with no I/O, database, or framework, because it had already failed twice on arithmetic a five-line unit test would have caught
Drew hard boundaries: the system doesn't decide, doesn't identify plants from photos, doesn't control hardware, and doesn't gamify. Automated writes to an irrigation controller with a drift bug is a way to kill sixteen trees overnight
Results & Impact
53
Plants Tracked
3
Kinds of Truth Reconciled
36
Facts Flagged Unverified
- Wrote a full solution architecture that deliberately excludes schema, API routes, and UI markup — five layers (Record, Reconcile, Observe, Compress, Surface), each depending only on the layers beneath it, so the build order falls out of the structure rather than out of preference
- Built a working single-file prototype: aerial site map with plant placement, a daily view that answers 'what fits in the time you have', a region-by-region tend view, a walk route, and a gaps view — all driven by the same ranked model
- Made provenance cross-cutting rather than decorative. Every fact carries a confidence, a source, and a verification timestamp, and an assumed value propagates its uncertainty to every number derived from it — visible wherever that number appears, not just at the source field
- Designed an attention ranking on cost of delay rather than severity: priority = severity × time sensitivity × irreversibility ÷ effort. The archetype it surfaces is a wire coil against a young trunk — a plant that looks fine today, five minutes of work, and death if ignored. No severity-sorted list finds it
- Made the diagnosis module store the entire differential, not just the chosen cause, so when a treatment fails the operator returns to hypothesis two instead of restarting the reasoning