What the tool does
The Anomaly Upload Validator checks blade inspection exports before they go to the next platform, converts field values across three naming systems, and hands back a formatted spreadsheet ready for review. It started as a single HTML file on a shared drive, with nothing to install.
The tool itself is internal. Its spec, test cases, data dictionary and release notes are public, with client details removed. It went from v1.0 in May 2026 to v3.1.4 in September, and nearly every version exists because the previous one met real data.
Right about the fields, wrong about the data
v1.0 treated an empty Asset or Coordinates field as an error. The first round of testing showed those values usually lived in internal records and simply weren't part of the export. Every one of those flags was a false positive, and each one made the compliance score a little less believable. v1.1 added a third status, Check Internally, and took those rows out of the score.
v1.2 went further. Real exports wrote Blade Side as full names, not the two-letter codes the spec expected, and Serial Number wasn't reliably there at all. It moved from required to conditional, and the required field count went from 19 to 18.
The pattern: I wrote the first spec from the upload requirements, not from the files people actually had in hand.
The failures that don't throw errors
The most expensive class of bug was the silent one. In v2.4, several output columns were writing a header with nothing beneath it. The field definitions had been correct since v2.1. The column matcher simply had no signature for those fields, so it never connected the input column to its name, and the export found nothing to write.
The release notes name it as a class, because it showed up more than once: an unmapped field loses its values silently, with no error and no flag, because nothing in the pipeline knows the value was supposed to be there. v3.1 was the same shape: Blade Chamber and Chord (%) had correct headers and empty cells in every export.
v2.5 was a quieter version of it. The output Asset column carried turbine identifiers, while the tool's own validation logic assumed Asset meant the blade. The two had disagreed since the conversion engine shipped, and nothing compared them, so nothing complained.
What I took from it: test for the presence of values, not only the absence of errors.
Small things that weren't small
The clickable image links in v2.6 opened a browser and then failed, because the URLs were encoded twice. They looked correct to the eye. v3.0 fixed two date faults that came from a single line preferring a cell's display-formatted value over its underlying one.
v2.7.1 corrected a company name rendered wrong in four of the eight derived output headers. An earlier limitation log had recorded one of those spellings as preserved intentionally, as if something downstream depended on it. I had written down an assumption as a fact, and it sat there for months looking like a decision.
Writing down what I couldn't prove
The dates for v2.2 through v2.7 weren't recorded when they shipped. I reconstructed them in September from files the tool itself produced, and the release notes say so, version by version, along with the weakest point in that evidence. The gap between June and September is stated as a gap. I don't know whether the work paused or went unreleased, and the document doesn't pretend to.
That's the same rule I keep for this site: every claim points to a source, and when the source isn't there, the claim says so or comes off the page.
What I'd tell myself in May
- Write the spec against real exported files, not the upload requirements.
- Check that every expected output column has values, not just a header.
- Treat "preserved intentionally" as a claim that needs a source.
- Date a release on the day it ships.
The spec says what I meant. The release notes say what happened. If you build internal tools, especially with AI in the loop, I'd like to hear which of the two you'd rather be judged on.
Kiley