Not a chatbot: what the assistant is allowed to say
The language model on the box is small, local, and forbidden from answering out of its own head about your grow. Here is what it is allowed to say instead, where that comes from, and the day the rule was so strict it looked broken.
A fair objection to putting a language model anywhere near a plant is that language models give the popular answer, not the correct one. They are trained on the internet; the internet is mostly forum lore, manufacturer copy and confident repetition; and a model that has read all of it will hand you the consensus with the same tone whether the consensus is right or not. We agree with the objection. The assistant on the Croplock hub is built on the assumption that it is true.
So the model is not asked what it thinks. It is asked to narrate from two sources it did not write, and it is checked afterwards to make sure it did.
Source one: the knowledge pack
Everything the device knows about a species lives in a pack — a JSON file, signed, loaded at boot — and nothing species-specific lives anywhere else. The cannabis pack currently carries 43 protocols: the VPD bands per phase, the leaf-temperature rules, the dry-room targets, the pest and pathogen signatures, and so on. Each protocol is a set of parameters, and 34 of the 43 reference the pack’s citation registry: 52 entries, every one with a DOI, 51 of them also resolvable in PubMed Central. A band in the pack is not “what growers say”; it is a number with a paper behind it, and the paper’s identifier ships on the device.
We audited that registry in June, and the audit is worth describing because of how it nearly went wrong. Two author-name web searches for one citation came back empty, and the first conclusion was that the entry was fabricated. Resolving its PubMed Central identifier — one call — returned the exact paper, author and institution matching. The search was the weak instrument, not the citation. Every identifier-bearing entry in the registry resolved the same way. A miss from a weak proxy is not evidence of absence; resolve the authoritative identifier before you call anything fabricated. We now apply that rule to ourselves before we apply it to the model.
The pack also carries a small knowledge base — 24 entries, at present — of general cultivation facts written in our own words with their source named. That section exists because of a failure described below.
Source two: the device’s own readings
When you ask about your grow, the question is answered from a context assembled at that moment from the hub’s records: the sensor readings, the pack band that applies to the current phase, the recent advisories. The model gets those facts and is told to answer only from them, to state the reading it used, and to say so if the facts do not cover the question.
Then the answer is checked. A guardrail parses the output into a structured shape — prose that cannot be checked is refused, because unparseable prose is where fabrication hides — and requires that the answer state the value of at least one real reading from the context. An answer that names no real reading is refused, whatever it claims to cite.
That last design choice came from a bug. A 3-billion-parameter model turns out to be reliably value-correct and unreliably identifier-correct: it will write “humidity is 47.7%” perfectly and then cite a source identifier that does not exist in its context — not because it invented the number, but because it garbled the label. An early version of the guardrail checked identifiers and refused correct, grounded answers as fabricated. The current one anchors on the value: grounding is decided by whether the answer states a reading that is actually in the context, rounding-tolerant, and the model’s citation identifiers are advisory — used to tell a missing citation from a wrong one in our telemetry, never to decide whether an answer passes. Trust the thing the small model copies reliably.
The refusal reasons are a fixed list, and each is a distinct failure: no grounding data at all; no fact matching the question; unverifiable output; an empty answer; an uncited claim; a fabricated citation; a claim about the grower’s readings that the readings do not support; and an answer that contradicts a fact it was given. Every refusal is recorded with its reason. That list is, in effect, the specification of what the assistant is not allowed to do.
The day the rule was too strict
For its first weeks the grounded rule was the only rule. Grounding was the sole pass condition, so any question that was not a claim about the grower’s own plants failed the guardrail identically. Asked “what is the difference between Indica and Sativa?” — a textbook question any free chatbot answers — the assistant returned a refusal and a paragraph explaining that it could not offer general growing advice. On a device sold as a cultivation intelligence platform.
The founder’s reaction was that it rejected far too often and that it made the AI look broken. He was right. A product that refuses the easy question does not look principled, and the refusal rate was teaching people to stop asking.
The error was a category collapse. Two kinds of question had been treated as one. A claim about this grow — “what is my VPD?”, “do I have pests?” — is where a model can fabricate your data, and the strict rule is right and unchanged there. A general question — “what is VPD?”, “what does topping do?” — makes no claim about your plants, so fabricating your data is not a possible failure. The guardrail had never been needed there; it fired anyway.
The fix was not to loosen the rule. It was to split the input by risk. A router sends a question about this grow down the grounded lane exactly as before. A general question goes down a second lane that retrieves from the pack’s knowledge base and answers from that plus the model’s own competence. The two lanes return distinguishable results, and the answer carries a label — GROUNDED or GENERAL_KNOWLEDGE — that the screen shows: a general answer is badged “General guidance — not from your grow’s data.” Honesty is preserved by labelling, not by refusing.
Two details made it work. First, the edge between the lanes: when the grounded lane concludes that the grow’s facts do not cover the question, it now falls through to the general lane instead of dead-ending. That one edge turned the refusal wall into an answer and made router mistakes cheap — a misrouted general question still gets answered, one inference later — while the router defaults to the strict lane when in doubt, because a misrouted grow question is the expensive direction. Second, the new lane needed its own guardrail against its own mirror-image failure: general guidance drifting into invented specifics about a grow it cannot see. That rule refuses an answer that asserts one of the grower’s readings, and it was written deliberately narrow — it fires only when a sentence addresses the grower, names something the hub measures, states a number, and is not hedged. “Check your lower leaves” passes. “Most growers target 1.0–1.5 kPa” passes. An over-tight rule there would have recreated the original problem one level down.
What it cannot do, stated plainly
It cannot cite what the device has not measured. When growers asked “should I flip to flower?”, the grounded lane had no fact to anchor on — the hub had readings, but nothing that was an answer to that question — so it correctly fell through to general knowledge, which is honest and also useless for a decision. The fix is never to let the model guess; it is to give the device something to compute. Data on the hub is not the same as a fact the model may cite, and the gap between them is where our engineering time goes.
The citations back the bands, not the prose. A protocol’s numbers have papers behind them. The sentences the model wraps around those numbers are the model’s, checked for grounding, not for eloquence.
Where the literature is empty, the pack says so. There are no peer-reviewed publications on cannabis curing; the dry-room targets come from a published handbook and are labelled as such, and our own page on the subject says the same thing in the first paragraph.
Behaviour is fragile across model changes. Moving the model from one quantization to another preserved its citation discipline and silently lost a self-refusal behaviour it had before — declining a hypothetical it had no data for. Nothing in a quality score caught it; a fixed set of behavioural cases now runs before any model, quantization or runtime change ships. That story is told in full elsewhere.
The category’s own model agrees
We did not have to make the case for provenance ourselves. On a grower forum this summer a member pressed a frontier chatbot on where its cultivation advice came from, and it conceded it had blurred manufacturer recommendations, breeder claims, plant physiology and grower lore together and, in its words, “presented them with more confidence than was warranted.” Another member documented the same model recommending a lamp distance with a product-marketing page as its source, rated it about as accurate as a forum, and concluded that an AI constrained to real grower knowledge would do better. Nobody in that thread wanted more refusals. The complaint, every time, was confident wrongness.
That is exactly the failure the two lanes are built to make structurally impossible: a number from the pack arrives with its source, a number about your tent arrives with its reading and timestamp, and anything else arrives labelled as what it is.
What we would tell someone starting this
- Separate the knowledge from the model. Put it in a file with identifiers, load it at boot, audit the identifiers. The model narrates; it does not know.
- Check the output, not the prompt. Instructions are suggestions to a language model. A post-hoc guardrail with a fixed list of refusal reasons is a contract.
- Anchor on what the small model copies reliably. Values, not labels.
- Split by risk class before you tighten anything. One rule for everything will over-refuse the safe questions and teach people to stop asking.
- Label, then answer. A general answer with an honest badge beats a refusal with a lecture.
- Every decision question needs a fact behind it. If the device cannot compute the thing, do not let the model guess it.
- Re-run the behaviour suite on every model change. Refusal behaviour does not survive quantization on its own.
Sources
Pack counts are from the shipped cannabis pack as of 2026-09-09: 43 active protocols, 52 registry citations (all with a DOI), 24 knowledge entries. The citation audit is from 2026-06-11. The two-lane design and the over-refusal it fixed are from our architecture record of 2026-07-21; the field observations are from a public grower-forum thread of July 2026, paraphrased except for one short attributed quotation. The guardrail description is of the code as it runs on the hub. Nothing here is a claim about the model’s accuracy; it is a description of what the model is permitted to say and how that is enforced.