Your pepper plant. The app has no model for pepper, so it refused to diagnose it — and then asked you for something.
“Tell us what you see — your label helps us add it.”
That sentence is the entire teaching feature, and it is a promise: give us a label and the gap closes. The question worth answering before building any more of it is simple — if you answer, how much does it actually buy?
What a handful of your labels is worth
Measured on arabica coffee leaf rust — a crop with no model in the app at all. 1401 labelled leaves, 605 of them rusted. Guessing the commoner answer scores 57%; that is the number to beat.
| examples you give it | 1 | 3 | 5 | 10 | 20 |
|---|---|---|---|---|---|
| the learned representation | 64% 52%–78% | 79% 68%–86% | 80% 69%–88% | 85% 76%–88% | 89% 85%–90% |
| a generic ImageNet network | 60% 49%–73% | 67% 57%–75% | 72% 63%–79% | 75% 66%–80% | 81% 75%–84% |
| colour alone — no learning | 66% 42%–76% | 72% 62%–78% | 73% 59%–79% | 75% 69%–78% | 76% 71%–78% |
| labels shuffled (must be chance) | 47% 23%–70% | 49% 24%–78% | 42% 28%–68% | 51% 25%–77% | 49% 22%–73% |
Each cell is the median of 40 runs, 10th–90th percentile beneath. One draw of a small example set is not a measurement.
So: one photograph is not teaching. A handful is. What earns its place is the fifth label and the twentieth — and the gap is still widening at twenty.
What the app does with your answer today
Define any crop and condition in your own words, photograph it, group the shots by plant, and record what you see. Your answer is frozen before any result is revealed, so a model score cannot nudge it. Everything stays on the device.
What it refuses to do, and why
The matching core is written and testable, and its output cannot encode a disease class, a probability or a learned region — so even a mistake cannot become a diagnosis. It is dormant because no encoder is cleared to feed it, and it says so by name:
| stored reason | when |
|---|---|
| available_teaching_result_activation_rejected | a provider returned a result anyway — it is replaced, and your photograph is still saved |
| personal_matcher_execution_failed | inference raised — the sample is committed with no partial score |
A preflight gate decides when that changes. It currently returns insufficient evidence, at 5 of 18 requirements, across 10 data sources of which none is yet eligible.
Every requirement, and what each one means
| requirement | what it means | |
|---|---|---|
| ✔ | canonical_audits_present | passes |
| ✔ | canonical_audit_contract | passes |
| ✘ | probe_reconstruction_present | The corpus audit has not been rebuilt from scratch and compared against the committed one, so the record cannot be shown to still describe the data. |
| ✘ | probe_matches_git_index_audits | Follows from the above: with no rebuild there is nothing to compare. |
| ✘ | encoder_checkpoint_rights | No encoder is cleared. The candidate embedding is DINOv2's, and its licence for this use is unverified — there is no teaching_encoder_evidence.json at all. |
| ✘ | canonical_leakage_gate | The corpus leakage audit does not yet come back with zero exact overlap, so a support image could reappear as a query. |
| ✔ | eligibility_inventory_present | passes |
| ✔ | eligibility_inventory_exact_source_coverage | passes |
| ✘ | eligibility_global_independence | 0 of 31,532 records carry the cross-partition independence evidence that would let support and query be called independent. |
| ✘ | purpose_specific_rights | 0 of 10 sources declare rights for this specific purpose. Rights for research do not imply rights to store an embedding of the image. |
| ✘ | physical_grouping | 0 of 10 sources record which physical plant each photo is of. Without it, teaching from one photo and testing on another of the same plant looks like success. |
| ✘ | reviewed_labels | 0 of 10 sources carry labels anyone has reviewed. |
| ✘ | required_controls | 0 of 10 sources declare the negatives and look-alikes a match has to be tested against. |
| ✘ | source_denominator_inventory_locked | No source has a complete no-exclusion inventory, so a quiet exclusion could not be detected. |
| ✘ | eligibility_evidence_derived | The eligibility rows are declared rather than derived from the data. |
| ✘ | encoder_transfer_strata | With none of the above, the held-out-condition and held-out-crop strata come out empty — there is nothing to measure transfer against. |
| ✘ | oriented_pixel_identities_verified | Not reached. The cheap metadata gate failed first, so no image was decoded — which is the gate working as designed. |
| ✔ | authorization_trust_anchors_committed | passes |
Run it yourself: python scripts/run_teaching_fewshot.py
--step preflight --run-id 20260922_demo, bound to commit
a0d44abd8a.
What it would take
Two things, and only one of them is engineering.
An afternoon in a garden
The failing requirements reduce to two facts that must be recorded as the photograph is taken and cannot be recovered later: which physical plant it is, and what a person says is wrong with it. That is why the 26 existing captures cannot be reused — their manifest records sample-to-plant mapping unknown, and no disease labels.
- Group every photo by physical plant, at capture time. The app already has the control.
- Hold out whole plants, not photos — another site, another day, different light.
- Include negatives: the same species without the condition.
- Include look-alikes: buds, seed pods, galls, insect eggs, water droplets.
- Balance by unique plant, never by photo count. Aim for eight plants with and eight without.
The measurement above says how many photographs per plant are worth taking: more than one, and the returns were still rising at twenty.
An encoder decision — yours
The representation above is DINOv2’s — not a declared output of any bundled model, and its licence for this use is unverified. Exporting it is a separate, gated decision.
What this page does not claim
- Nothing has been taught to the app. The measurement ran off-device on public coffee imagery, with the owner’s authorisation, purely to find out whether labels would be worth collecting. The matcher is still dormant and the gate is untouched.
- Held-out leaves, not held-out plants. The coffee set records no plant identity, so two leaves from the same tree can land on opposite sides of the split. That inflates the numbers, and it is the very requirement the gate fails hardest.
- These are easy photographs. Single detached leaves, plain background, even light. A phone photograph of a plant in a garden is harder, and nothing here predicts how much.
- One condition, present or absent. Not a diagnosis among many candidates, which is the harder problem and the one a grower actually has.
- The source data has holes. Of 1747 labelled rows, 345 have no image file and 1 is unreadable; 1401 were used.
Rebuilt with python scripts/render_app_demo.py --page
teaching; the measurement is
scripts/measure_teaching_fewshot.py and its artifact is
data/derived/teaching_fewshot/coffee_rust.json.