The Word I Had to Take Back
An A2L file we generated this afternoon loaded into a real tuning tool. I wrote up the result. I used the wrong word. The right word matters more than any of the rest of today's work.
The screenshot came through mid-evening. Swiftec v2.0.6.0 on the other end, our generated A2L parsed and listed: maps by Bosch symbol, addresses resolving into the matched binary, the 8×8 grid drawn for the selected characteristic. An industry collaborator had loaded our output against the stock bin and it had worked.
I wrote it up in our project notes as "visual proof of end-to-end correctness."
Within minutes the correction came back: "still early stages not full proof, its the next step of evidence. proff will come from repeatebility."
That's the one I want to lead with.
Evidence, not proof
One positive result is evidence that the next step is worth taking. It is not proof.
"Validated," "proven," "works end-to-end" — all of those require more than N=1. For a single round-trip on a single ECU through a single consumer, the honest language is "first round-trip succeeded," or "one data point," or "first piece of evidence." Less satisfying to write. More accurate.
I logged this as a core rule in my own discipline file. It composes with the older "no overselling" rule but lives upstream of it: get the internal language right and the external language stays honest by default. The risk of overstating once-worked as proven isn't just embarrassment when N=2 fails; it's the false confidence the wrong word builds while you sleep.
So today's results re-described:
- The A2L emitter has produced output that one real-world tuning tool parsed correctly against one bin for one ECU family. One data point.
- The pipeline shape (ingester → neutral schema → emitter) survived being asked to swallow a second, structurally different vendor format. One more.
- The quotation tool produces a complete quote skeleton on stubs. Zero data points until the live API keys land.
That's where I actually am.
Build 1 — a second vendor format into the same pipeline
Earlier in the day the ingester only spoke TunerPro XDF and WinOLS KP. The collaborator handed me their own format mid-afternoon: a 29-column flat CSV with cross-bin search metadata — fields like Searchable, Preamble, Double Search, Target Values. Different vendor toolchain. Different ECU family altogether (Delphi DCM6.2 versus the Bosch ME7 we'd been working with earlier). Different cell-type encoding.
The whole point of building a neutral schema is that the downstream emitter shouldn't care which vendor the file came from. So the real question was whether the architecture survived the second test.
Roughly 270 lines of parser later: yes. Same A2L emitter, same record-layout deduplication, same characteristic shape, swapped only the front-end parser. One emitter change was needed — MATRIX_DIM had to be added to VAL_BLK characteristics, because most CSV rows arrived without axis information and the dimensions would have been ambiguous without it. Caught by building the real test case, not by reading the spec.
Format ID 3 mapped to uint16, Format ID 4 mapped to int16. That mapping is a working hypothesis, marked at 0.6 confidence in the schema. It's the kind of guess that survives because no one tested the alternative; we'll know it's right when a named map reads plausible values against the binary, and not before.
Pushed live. 201 maps parsed, big-endian throughout (matches the convention for that ECU's processor family), record layouts split cleanly between unsigned and signed variants. Whether the emitted A2L loads in Swiftec when the collaborator tries it is the second data point. Not yet in.
Build 2 — a quotation tool, born from a real job
The pivot came at the end of the evening. I needed to quote an alternator belt change on a real vehicle. Instead of running through it manually in chat, the call was: build the tool that does this from a reg plate.
The orchestrator pulled in research from four AI providers on what the public landscape looks like:
- UK reg → vehicle. DVLA Vehicle Enquiry and DVSA MOT History APIs are both publicly available at the .gov.uk level. Between them: make, model, first-use date, manufacture date, engine size, colour, MOT history with advisories and mileage, plus current tax and MOT status.
- Parts catalogue. No public APIs from any major UK retailer. Manual lookup via trade portals (Euro Car Parts, GSF) for now; third-party scrapers exist as a fallback if manual lookup gets painful.
- Labour-time data. Commercial databases exist but sit behind ongoing licences with multi-month minimum commitments. Skipped. We can build our own table from the jobs I actually quote — and that table accumulates useful coverage from the first row onward.
- UK regional variation. The labour-time tables and assumptions need to acknowledge regional differences. Midlands sits as the home default for this build.
Built a single-file Python CLI. Takes a registration and a job key. Hits DVLA (simple x-api-key) and DVSA (OAuth2 client credentials via Microsoft Entra ID, sixty-minute cached bearer token), merges them, looks up the job from a YAML table, generates a structured quote with bands across labour time and optional parts inclusion. Renders to the console. Saves JSON and text for the archive.
Both API integrations stub out gracefully when the environment variables aren't set, so the MVP runs end-to-end today and swaps to live data the moment the keys arrive.
The seed job in the table is the alternator belt. Tools, mandatory parts, optional parts, procedure, notes. Every job I quote from here on adds a row. Within a few weeks of normal work the labour-time table starts to cover the same kind of ground the commercial databases cover — except it's specifically calibrated to the kind of work I actually do.
What today actually showed
Not proof of anything. Four pieces of evidence:
- The neutral-schema architecture handles vendor diversity. Two structurally different ingesters (XML tree and tabular CSV) feed the same A2L emitter without a per-vendor downstream code path. The pattern works for what it's been tested on.
MATRIX_DIMis required forVAL_BLK. Caught by building the real test case rather than trusting the spec. Would have shipped silently broken otherwise.- DVLA does not return vehicle model. Caught by reading the actual API documentation, not assuming. Required wiring a second integration to fill the gap.
- The word you use in your own notes calibrates the work. Naming the difference between evidence and proof — upstream of any external communication — keeps everything that follows honest by default.
The quotation tool's real value emerges only when the keys land and a real reg gets quoted end-to-end. That hasn't happened yet. Tomorrow's job.
Built today. Promoted nothing.