“Received” isn’t “complete”
A submission can arrive without its photo. The count shows every record as received, while the image survives only on the tablet.
Survey teams reset their tablets between rounds, and that reset is when unsent records and photos disappear for good. LastCopy compares every tablet’s original export with the server, byte for byte, and gives the coordinator one answer per device: safe to wipe, recover first or hold, with a certificate that proves why.
1 record byte-for-byte, every referenced file included.
The whole record uuid:fleet-03-b
More than 2 million people use ODK to send over 250 million submissions a year, in 194 countries, including WHO surveillance for polio and cholera. Before every reset, someone has to decide whether a tablet still holds the only copy of something.
A submission can arrive without its photo. The count shows every record as received, while the image survives only on the tablet.
Repeated answers drop out of the CSV export, so data looks lost even though the raw XML on the server has all of it.
The only real check is opening XML and media files one by one, for every tablet, at the end of a long field day. So nobody does it.
Sources: getodk.org · Digital Public Goods registry.
An investigation is a loop planned by a World Model. Nemotron forms and critiques hypotheses, a deterministic verifier settles them against the original bytes, and a fixed rule clears each tablet.
Four cross-source SQL joins over tablet exports, the server capture and the spreadsheet view find every suspicious record.
The Investigator turns each suspicion into a testable hypothesis. The Reviewer approves it or sends it back, before anything is fetched.
The verifier compares original XML and every file slot. A refuted hypothesis is logged as a changed decision.
The gate clears only what the bytes prove. An Adversary then tries to break every clearance, and code must answer each objection or the tablet is held.
Each verified record lands in exactly one bucket, and the buckets decide the answer in a fixed order: anything missing wins, then anything uncertain, and only then “safe”.
Set what the verifier found when it compared the tablet’s export with the server, byte for byte.
The tablet holds the only copy of something the server lacks.
Fig. 2The same rule, in the same order, as lastcopy/agents.py · wipe_gate. Missing data always beats “looks fine”, and a tablet that never exported is never treated as clean.
The obvious question is whether the answers were planted. So a generator builds fleets the agents have never seen, with a random hidden condition on every tablet, and the full loop runs: planner, SQL, hypotheses, verifier, gate and Adversary. The truth is revealed only after each decision.
| Fleets decided entirely correctly | 500 / 500 |
| Tablets decided correctly | 1,980 / 1,980 |
| Tablets wrongly cleared to wipe | 0 |
| Truth: Safe to wipe | 531/531 |
| Truth: Recover first | 921/921 |
| Truth: Hold | 528/528 |
| Answer edited on the server | 510/510 |
| Whole record never arrived | 493/493 |
| Tablet never exported | 237/237 |
| Photo never uploaded | 530/530 |
| Record matched the server | 997/997 |
| Spreadsheet hides answers (raw XML has them) | 520/520 |
Reset twenty tablets before tomorrow’s round without gambling on any of them.
A list of tablets to wipe now, and the exact file to upload from each of the others.
Stop chasing “missing” answers that are really just artefacts of the export view.
Raw-XML checks that separate export gaps from real loss, with SQL and hashes to audit.
Show funders and ethics boards that nothing collected was silently lost.
A hashed certificate per tablet, and a trace of how every decision was reached.
The Meterless World Model holds the investigation as a graph and picks each next step from its state. Python only runs the step it picks.
Selects the next action from graph state: triage, classify, review, fetch, evaluate, remedy, decide, explain.
MeterlessFour cross-source joins that find suspicious records.
ZetarisProposes a hypothesis and the evidence that would test it.
NemotronApproves, revises or rejects. A code guard enforces it.
NemotronResolves exact source objects and re-checks every hash.
ZetarisCompares original bytes. The only source of verdicts.
CodeChooses only among the actions code permits.
NemotronSeven criteria must all hold; one decision and a hashed certificate per tablet.
CodeTries to break every clearance; each objection is re-checked from the raw tables.
NemotronPlain sentence; every ID and filename checked.
Nemotron# decided by code from verified findings only if device in missing_devices: decision = 'HOLD' # never exported elif any(v in MISSING for v in verdicts): decision = 'RECOVER_FIRST' # only copy is here elif any(v in UNCERTAIN for v in verdicts): decision = 'HOLD' # a person decides elif not findings: decision = 'HOLD' else: decision = 'SAFE_TO_WIPE'
Verdicts come only from the byte comparison; the gate never reads model output.
Strict JSON from every model call; one repair attempt, then a fallback that the trace names as one.
12 steps, 2 critique rounds, 10 model calls, 300 seconds, or a controlled failure.
On 27 October the five-tablet fleet ran end to end: evidence through a local Zetaris install, judgement through NVIDIA Nemotron via Meterless Nightshift. The decisions match the keyless sample run, because code makes them.
| Tablet | Decision | Explanation written by Nemotron, citations checked | Certificate |
|---|---|---|---|
| tablet-01 | Safe to wipe | The export is view-only, but 2 completed records matched the server byte-for-byte, including every referenced file. | 3817eee857f4… |
| tablet-02 | Recover first | Finding-3: the file b.bin for uuid:fleet-02-a is not on the server. Automatic recovery is not permitted, so recover it with a reviewed upload. | 010021268577… |
| tablet-03 | Recover first | Finding-5: the whole record for uuid:fleet-03-b is not on the server. Automatic recovery is not permitted, so recover it with a reviewed upload. | d9283680e82a… |
| tablet-04 | Hold | Finding-6: the server copy of uuid:fleet-04-a has different answers; a person must choose. | 2eccf72550b2… |
| tablet-05 | Hold | No export was received from this device, so nothing on it has been checked. | 231f4d001424… |
Tablet exports, server capture, spreadsheet view and file references are registered as tables. The Scout’s joins over them are the only way the agents learn where to look.
Suspicions, hypothesis revisions, findings, remedies and decisions live in its graph, and it chooses every next action from that state.
Investigator, Reviewer, Advisor, Adversary and Explainer run on NVIDIA Nemotron through Meterless Nightshift. Every trace line records the model that actually answered.
No. Verdicts come only from the deterministic byte comparison, and the wipe gate reads only those verdicts. Models choose where to look, critique hypotheses, pick among permitted remedies and write the explanation, and that explanation is checked token by token against the evidence.
That every completed record and every referenced file from that tablet’s export was found on the server with identical bytes. The certificate names the rule version, both archive hashes and every finding. It does not prove the answers are true, and it only covers the exports you supplied.
Because the CSV export can leave out repeated answers that the server actually holds. LastCopy checks the raw server XML; when every answer is there, the gap is in the view, not in the data.
Yes. python run.py runs the full loop in Sample mode in a few seconds: planner, SQL on SQLite, verifier, gate and checks. Only the model roles are replaced by a written policy, and every trace line says so.
Never. Archives are read-only and sealed with SHA-256. Live recovery writes only to a dedicated synthetic ODK Central test project.
ODK Collect v2026.3.5 exports against ODK Central v2026.3.1. Encrypted forms and KoboToolbox are on the roadmap, not claimed today.
No keys, no network. Clone the repo and run one command, or step through the live investigation in your browser.
$ python run.py tablet-01 SAFE_TO_WIPE raw XML holds every answer tablet-02 RECOVER_FIRST b.bin is not on the server tablet-04 HOLD server answers differ; a person must choose