Build record and quality
Every robot gets a serial number and a build record: a JSON file that says what went into it, which checkpoints it passed, and its calibration. It is telemetry like any run: indexed in Elasticsearch, so "which robots have fuse lot 2311?" is one query.
The build record
{
"serial": "MB-0001",
"revisions": {"bom": "H2-r1", "pcb": "carrier-v1.2.0", "software": "git:08d9263"},
"parts": [
{"bom_row": 3, "part": "ZED-F9P board", "supplier": "…", "order": "…", "lot": "…", "receiving": "pass"},
{"bom_row": 0, "part": "STOP button", "lot": "…", "receiving": "pass"}
],
"checkpoints": [
{"id": "H1-C", "result": "pass", "measured": {"fix_s": 74, "scatter_95_cm": 1.8}, "by": "…", "at": "2026-…"}
],
"calibration": {"antenna_xyz_m": [0.0, 0.0, 0.42], "imu_rpy_deg": [0.3, -0.5, 0.0]},
"acceptance": [{"gate": 2, "run_id": "…", "report": "coverage", "result": "pass"}]
}
A robot ships (or goes on the lawn unattended) only when every checkpoint and every gate passed on its current revisions. Changing a safety-chain part, the PCB revision, or the software that runs the safety gate means re-running gate 3.
Quality controls
| Control | What | When |
|---|---|---|
| Receiving inspection | The checks on arrival; safety-chain parts: every part. Other parts: a sample of each lot | Every delivery |
| First-article inspection | The first robot of a new BOM or PCB revision goes through every checkpoint and every gate, with photos | Each new revision |
| Checkpoints | The pass/fail tests at the end of each sub-assembly | Every robot |
| End-of-line test | One script on the finished robot: every sensor and actuator, the STOP and blade stop times, the watchdog | Every robot |
| Defect log | Every failed checkpoint, field return and safety event: what, which serial, which lots, the cause, the fix | Always |
| Revision control | BOM and PCB revisions are in the repository and on the build record; no unrecorded changes | Always |
Build records live in the repository as build-records/<serial>.json, so every change to one is a commit.
make build-record-eol SERIAL=MB-0001 RUN_ID=<run> # add an end-of-line result, stamped with the current revisions
make builds # validate every record, index them into Elasticsearch, print status
make builds prints what each robot is allowed to do on its current revisions: drive blade-off needs a clean
record and an end-of-line PASS; supervised mowing also needs gates 2 and 3. A result on an older software, PCB or
BOM revision is history, not evidence, so changing a revision silently withdraws those permissions until the tests
are rerun. In Elasticsearch, mowlark-builds has one document per robot and mowlark-build-parts one per part:
"which robots have fuse lot 2311?" is a term query on lot.