← Anomaly Upload Validator

Anomaly Upload Validator · Specification artifact

Release Notes & Changelog

What actually shipped.

This page is rendered from that DOCX. Same document, same words.

Anomaly Upload Validator: Release Notes & Changelog

Internal Tool · v3.1.4 · September 2026

Document Overview

This document provides a versioned history of the Anomaly Upload Validator, a browser-based tool that ingests raw inspection data exports from Input Source, validates them against Platform A upload specification, converts field values across three nomenclature systems (Input Source, then Platform A, then Platform B), enables human-in-the-loop resolution of unmatched values, and exports a formatted multi-tab XLSX working document.

Version Summary

Version Summary
VersionRelease DateStatusKey Milestone
v1.0May 2026ReleasedCore validator, field presence + format checks
v1.1May 2026ReleasedThree-tier status system: Error / Check Internally / Warning
v1.2May 2026ReleasedBlade Side expanded values; Serial Number made optional
v2.0May 2026ReleasedFull conversion engine + XLSX export with live formulas
v2.1May 2026ReleasedMulti-format support (Format A and Format B); ISBLANK bug fix
v2.2May 2026ReleasedBulk resolution of Manual Review flags
v2.3May 2026ReleasedContent-based column matcher; header detection; 3 bugs fixed
v2.4June 2026ReleasedPass-through field signatures; sheet order; 3 bugs fixed
v2.5June 2026ReleasedOutput schema change: Asset, Turbine SN, Asset SN split
v2.6June 2026ReleasedClickable image hyperlinks in the exported report
v2.7June 2026ReleasedURL entity double-encoding fix
v2.7.1September 2026ReleasedFour derived output header names corrected; LIM-07 closed
v3.0September 2026ReleasedDate handling: timezone shift and format fault corrected
v3.1September 2026ReleasedTwo output columns that wrote empty cells under correct headers
v3.1.1September 2026ReleasedExport column widths realigned; two field descriptions corrected
v3.1.2September 2026ReleasedAsset column width reduced to suit the v2.5 schema
v3.1.3September 2026ReleasedColumn widths fitted to content across 14 columns
v3.1.4September 2026ReleasedInput Source Component width set to an exact fit

On the v2.2 to v2.7 dates. These were reconstructed in September 2026, not recorded at the time. v2.3 through v2.7 each anchor to a dated artefact the tool itself produced — converted files carrying an export date in their name, and input files named by working date — which come from the machine clock and are dependable.

v2.2 was dated separately, and later. It produced no such artefact, and was first recorded here as inference from the releases either side of it. It has since been bracketed against the retained working files instead: bulk resolution is present in the build immediately preceding the column-matcher work and absent from the one before that, and those two builds are dated 1 May and 23 May 2026. That places v2.2 inside May on file evidence rather than on position in the sequence. The bracketing is sound in both directions; the residual weakness is that it rests on file modification times, which can record a later re-save. A Drive or chat timestamp from when bulk resolution shipped would still be the stronger record.

The June to September gap is real, not a lost record. No release occupies the span between v2.7 and v2.7.1, and no artefact has been found in it. Whether the work paused or simply went unreleased is not something this document can settle, but nothing is missing from the sequence.

v1.0: Core Validator

Release Date: May 2026 · Status: Released

Background

Wind farm asset owners use Input Source to conduct blade inspections. Datasets exported from Input Source as CSV or XLSX must be imported into Platform A before onward submission to Platform B. Prior to this tool, data coordinators manually checked each upload file, a time-consuming, error-prone process with no standardized output.

What Was Built

A self-contained HTML file deployable via shared Google Drive with no installation required. Accepts CSV and XLSX uploads, parses them client-side, and validates every row and column against Platform A upload specification.

Changes

v1.0: Core Validator
TypeFeature / FixDescription
FeatureFile ingestionDrag-and-drop or browse for CSV / XLSX. Parsed client-side via SheetJS, with no data transmitted externally.
FeatureColumn-level validationChecks all 19 required column headers present (case-sensitive). Flags missing columns with description.
FeatureRow-level validationValidates every required field: presence, format (date, severity range, Yes/No, blade side codes, coordinate pairs, numerics).
FeatureCompliance scorePercentage clean rows with color indicator (green 80% or above, amber 50% or above, red below 50%).
FeatureIssues tableTabular view: Row #, Anomaly ID, Field, Status, Detail.
FeatureFilter tabsFilter by All / Errors / Warnings.
FeatureValidation report exportDownload issues as dated CSV.
FeatureDataset summaryTotal anomaly count, unique turbine count, unique site count with per-site breakdown.

Known Issues at Release

v1.1: Three-Tier Status System

Release Date: May 2026 · Status: Released

Background

During initial testing it became clear that empty Asset and Coordinates fields may exist in internal historical records and simply weren't included in the Input Source export. Flagging these as hard errors created false positives and undermined trust in the compliance score.

Changes

v1.1: Three-Tier Status System
TypeFeature / FixDescription
FeatureCheck Internally statusNew third status (blue) for Asset and Coordinates when empty. Rows excluded from compliance score.
EnhancementCompliance score denominatorScore = clean rows / (total - check-internally rows).
EnhancementCheck Internally filter tabDedicated filter tab added to issues table.
EnhancementCSV export labelsThree-label Status column: Error / Check Internally / Warning.
EnhancementSummary stats cardFifth card added for Check Internally row count.

v1.2: Field Spec Refinements

Release Date: May 2026 · Status: Released

Background

Real Input Source exports revealed Blade Side uses full descriptive names, and Serial Number is not consistently available and should not block uploads.

Changes

v1.2: Field Spec Refinements
TypeFeature / FixDescription
EnhancementBlade Side expanded valuesAccepts full names: Value 1, Value 2, Value 3, Value 4 alongside Code 1/Code 2/Code 3/Code 4 codes. Case-insensitive.
EnhancementSerial Number made optionalSerial Number demoted from Required to Conditional. Empty value raises no flag.
EnhancementField counts correctedRequired 19 to 18. Conditional 3 to 4.

v2.0: Conversion Engine & XLSX Export

Release Date: May 2026 · Status: Released

Background

Data coordinators still needed to manually convert field values across three nomenclature systems using a separate Excel spreadsheet. This release embedded the conversion logic directly and produced a properly formatted output XLSX, eliminating the manual conversion step.

Conversion Flow

Input Source, then Platform A, then Platform B

Changes

v2.0: Conversion Engine & XLSX Export
TypeFeature / FixDescription
FeatureInput Source Component derivationConcatenates Component + Material (if present) using LEN() guard against empty strings.
FeatureInput Source Damage Type derivationConcatenates Type + Subtype (if present) using LEN() guard.
FeatureElement conversionThree-column output: Input Source Component to Platform A Element and Platform B Element via lookup.
FeatureAnomaly Type conversionThree-column output: Input Source Damage Type to Platform A Anomaly Type and Platform B Anomaly Type via lookup.
FeatureBlade Side conversionBlade Side to Platform A Blade Side and Platform B Blade Side.
FeatureManual Review statusAmber status when concatenated value not in conversion table. Original value preserved. Blocks XLSX export until resolved.
FeatureHuman-in-the-loop resolutionDropdown on each Manual Review row. Export unlocks when all resolved.
FeatureExport Converted XLSXTwo-tab output: Damages Report (all columns, live VLOOKUPs) + Conversions (editable mapping table for Engineering).
FeatureLive VLOOKUP formulasDerived columns reference Conversions tab. Engineering adds rows; formulas update automatically.
FeatureColumn normalisationAlias map handles variants: Date to Inspection Date, Turbine Serial Number to Serial Number, Links to Source Images, etc.
EnhancementFloating point cleanupNumeric fields cleaned of floating-point noise on import.
EnhancementBlade letter extractionBlade field populated from Asset column when empty.

Known Issues at Release

v2.1: Multi-Format Support & Formula Fix

Release Date: May 2026 · Status: Released

Background

Testing with the Format B dataset revealed: (1) Format B exports use Component + Element rather than Component + Material, and Anomaly Type + Subtype rather than Type + Subtype. (2) Excel's ISBLANK() returns FALSE for empty string cells, causing a trailing ' - ' on the derived value instead of the base value alone when Subtype is empty.

Changes

v2.1: Multi-Format Support & Formula Fix
TypeFeature / FixDescription
FixISBLANK to LEN() fixExcel formulas changed from IF(ISBLANK(Subtype),...) to IF(LEN(Subtype)=0,...). Handles both truly blank and empty-string cells.
FixFormat B Element columnDetects whether Material column is present. Falls back to Element column as component suffix if absent.
FixFormat B Anomaly Type columnReads Type column when present; falls back to Anomaly Type column when absent.
FixBlade field normalisationFormat B stores 'Blade A' in Blade column. Tool strips label prefix and retains letter for both formats.
EnhancementColumn alias expansionCOL_ALIASES extended with additional pass-through variants.

Datasets Validated

v2.2: Bulk Manual Review Resolution

Release Date: May 2026 · Status: Released

Background

Manual Review flags were cleared one row at a time. On a dataset carrying many unmapped values that is slow and repetitive, and it does not match how a data coordinator actually works: they recognise an unmapped value once, then want that decision applied everywhere it appears in the batch.

Changes

v2.2: Bulk Manual Review Resolution
TypeFeature / FixDescription
FeatureBulk resolutionMultiple unmapped values resolved at once through dropdown selection rather than row by row.
UnchangedExport gateExport Converted XLSX remains disabled until every Manual Review flag is cleared. Bulk resolution reduces the cost of clearing them, it does not remove the gate.

Documentation note

The sanitized SDLC document set was built at v2.1, not v2.2. This release was therefore the first one those documents never covered, which put the undocumented range at six versions rather than five.

That range was closed on 2026-09-18. The data dictionary, this document, the PRD, the user stories and the test cases were all brought current to v3.1.4. The note is kept because the six-version gap explains why several of those documents needed substantial revision rather than a version bump, and why the dates above had to be reconstructed rather than read off a record.

v2.3: Content-Based Column Matcher

Release Date: May 2026 · Status: Released

Background

Real files vary in column order, in column names, and in sheet structure. The fixed-layout assumption held only for files matching the canonical structure exactly, and broke on everything else. Three specific failures drove this release: the header row is not always row 1, because some files carry a work-order preamble block above it; two columns in the same file can share a name while meaning different things at different levels of the record; and the blade letter appears in at least four different shapes across sources.

Changes

v2.3: Content-Based Column Matcher
TypeFeature / FixDescription
FeatureContent-based column matcherTwo passes. A header-alias match first, then a data-shape fingerprint comparing each candidate column's values against the expected shape of the field. Handles renamed and reordered columns.
FeatureAutomatic header-row detectionUp to 25 rows of metadata preamble above the header are scanned and skipped.
FeaturePriority-ordered alias matchingA more specific alias wins over a general one for the same canonical field.
FeatureDuplicate-name disambiguationWhere two columns share a name, the closer data-shape match wins.
FeatureDistinct-value tiebreakerWhere shape scores tie, the column with more distinct values wins, which separates a constant-value column from the varying one that carries the real data.
FeatureView detected columnsCollapsible confirmation panel in the file-info line showing which input column was bound to each canonical field.
Fix (bug 1)Bare-letter blade extractionThe extraction pattern matched only full labels such as "Blade A" and missed files carrying a bare "A", "B" or "C". Now accepts both forms, plus dedicated Blade and Blade Position columns. Closes decision item D-1.
Fix (bug 2)Duplicate Component column collisionA file carrying two columns named Component, one at inspection level holding a constant value and one at anomaly level holding the real component, tied on shape scoring because both held valid components. The distinct-value tiebreaker resolves it in favour of the anomaly-level column.
Fix (bug 3)Duplicate Type column collisionThe same file carried two columns named Type, one a task type and one a damage type. Shape scoring selected the damage type correctly without needing the tiebreaker.

Provenance note

Bugs 2 and 3 were found in a file later confirmed to be a reconstructed illustrative example rather than a genuine export. The disambiguation logic is sound regardless, but whether duplicate column names occur in real delivered files is not established. Treat this behaviour as defensive until a genuine file exercises it.

v2.4: Pass-Through Field Signatures, Sheet Order, Conversion Key

Release Date: June 2026 · Status: Released

Background

Several output columns were writing a header with nothing beneath it. The cause was not the export and not the specification: the matcher held no field signature for those fields, so it never bound the input column to the canonical name, and the export lookup returned nothing. The field definitions had been correct since v2.1. This is the same failure pattern as an earlier Links and Source Images issue, and it is worth naming as a class: 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.

Changes

v2.4: Pass-Through Field Signatures, Sheet Order, Conversion Key
TypeFeature / FixDescription
FixMissing field signaturesSignatures added for Propagation Type, OpSeverity, Monitoring Recommendation and Tasks. These fields were already defined and already expected; they were simply never bound.
FixInspection Date bridgeThe export cell writer now bridges the input field name to the output field name, which differ.
EnhancementSheet orderDamages Report moved to the first sheet position and Conversions to the second, matching the convention of amended files received from Engineering.
EnhancementConversion table key addedOne value present in a test file had no key in the conversion table and fell through to Manual Review on every occurrence. Added as its own key rather than treated as a subtype collapsing to its base value.
Fix (bug 4)Format B export produced bare row numbersWhere the input carried an Element column rather than a Material column, the export formula referenced an output column that does not exist in that format. The column-letter lookup returned empty and the formula collapsed to a bare row number, producing values such as "Blade - 2" and "Blade - 3". None match any conversion key, so every affected row fell through to Manual Review.
Fix (bug 5)Double concatenationAfter the row-number fix, some rows produced a doubled value such as "<Component> - <Component> - <Material>". Row processing overwrites the input field with the concatenated result, and the export writer was reading that already-transformed value and concatenating it a second time.
Fix (bug 6)Element section polluted by Blade Side rowsFour Blade Side entries were wrongly embedded at the top of the Element conversion array. Removed, with section-range arithmetic recalculating automatically.

Decisions

v2.5: Output Schema Change, Asset and the Two Serial Numbers

Release Date: June 2026 · Status: Released

Background

The output Asset column had been carrying turbine identifiers while the tool's own blade-validation logic assumed Asset meant the blade. The two had disagreed since the conversion engine shipped, without surfacing as an error, because nothing in the pipeline compared them. This release separates the three concepts that had been sharing two columns.

Changes

v2.5: Output Schema Change, Asset and the Two Serial Numbers
TypeFeature / FixDescription
SchemaOutput column D, AssetNow carries the blade letter, A, B or C.
SchemaOutput column E, Turbine Serial NumberNew. Carries the value previously written to the output Asset column.
SchemaOutput column F, Asset Serial NumberNew. Carries the value previously written to the output Serial Number column.

Verification: 73 of 73 rows on the test file matched the amended target exactly across all three columns.

Known Issues at Release

v2.6: Clickable Image Links

Release Date: June 2026 · Status: Released

Background

The exported report carried image URLs as plain text. Opening one meant selecting the cell, copying the string and pasting it into a browser, for every image a reviewer wanted to see.

Changes

v2.6: Clickable Image Links
TypeFeature / FixDescription
FeatureHyperlink attachmentA post-pass over the exported Damages Report walks the link-bearing cells and attaches any http or https value as a real Excel hyperlink, with target and tooltip. The URL stays visible as the cell's display text and Excel renders it as clickable.
CorrectnessNon-URL values left aloneSource Image Reference holds an identifier rather than a URL, and correctly remains plain text.
Fix (bug 8, unnumbered in the change log)Literal "None" leaking into outputSome source exports use the literal string "None" to denote a missing value. That string was passing through to the output as the word "None" rather than as an empty cell. Now normalized to empty at ingestion.

v2.7: URL Entity Double-Encoding Fix

Release Date: June 2026 · Status: Released

Background

The hyperlinks shipped in v2.6 opened a browser and then failed. The storage provider returned a not-found error for URLs that were, to the eye, correct.

Changes

v2.7: URL Entity Double-Encoding Fix
TypeFeature / FixDescription
Fix (bug 7)Ampersands double-encoded in URLsWhen the XLSX library reads a hyperlink from an input file it returns the URL with XML entities still encoded, so an ampersand arrives as &amp; rather than as &. Passing that value back to the same library to write encodes it a second time, producing &amp;amp; in the output file. The signed URLs used for image storage depend on exact character matching of the query-string signature, so any encoding drift invalidates the signature and the storage provider returns not-found. Fixed by decoding XML entities on ingestion, before the value moves downstream.

Verification: the output hyperlink is byte-for-byte identical to the input URL. 1355 characters, 6 ampersands, exact match at both ends.

Known Issues at Release

v2.7.1: Output Header Name Corrections

Release Date: September 2026 · Status: Released

Background

Four of the eight derived output columns carried a wrong rendering of a company name: two lower-cased a name mid-word, two transposed a pair of letters in another. Neither error was applied consistently, and one name appeared correct in one column and wrong in another within the same sheet. The v2.1 limitation log had recorded one of the two as preserved intentionally, which implied something downstream matched on the misrendered string.

Changes

v2.7.1: Output Header Name Corrections
TypeFeature / FixDescription
Fix (bug 9)Four derived output headers misrenderedColumns P, Q, U and Y corrected. The strings were a single namespace inside the tool, serving simultaneously as the output header, the row-object key, the conversion-field label, the Manual Review dropdown key and the lookup key for the column letters the export formulas are built from, so the correction had to be applied across all of them at once. Changing the header text alone would have left the formula builder resolving a key that no longer existed and emitting broken lookups.

On the "preserved intentionally" note. Before the change the tool was searched for every occurrence of all four strings. All were on the output side. The input-side column matcher — both its alias map and its field signatures — contained neither spelling, so no ingestion path had ever depended on a misrendered form. The intended asymmetry, correct on the way out and tolerant on the way in, turned out to be unnecessary: nothing needed tolerating. Files exported before this release ingest exactly as they did before.

Verification: the header row was read from the raw exported file rather than from a summary, because transcription normalises spelling silently, which is how the defect survived an earlier review. All four corrected, the four already-correct headers unchanged, column count and order identical.

LIM-07 is closed by this release, as copy error rather than convention. The casing error was never tracked and needed no entry of its own, having been found and fixed in the same change.

Known Issues at Release

v3.0: Date Handling Correction

Release Date: September 2026 · Status: Released

Background

Two faults in one line of the ingestion path, which preferred the library's display-formatted value over the underlying one for every cell.

Changes

v3.0: Date Handling Correction
TypeFeature / FixDescription
Fix (bug 10)Dates from CSV shifted back one day west of UTCThe XLSX library uses opposite conventions for the two input kinds: a date parsed out of CSV text becomes a timestamp at UTC midnight, while a date cell read from a real XLSX becomes one at local midnight. The display value is built with local accessors, so it was correct for the XLSX case and wrong for the CSV one. A 2026-04-12 inspection read from CSV displayed as 4/11/26 anywhere west of UTC. Fixed by stopping the CSV parser coercing text into dates at all, so CSV dates stay the literal strings the file contained.
Fix (bug 11)Every dated row failed its own date-format checkThe display value renders as 4/12/26 in every timezone, which never satisfied the YYYY-MM-DD rule that both the date field signature and its validator test. Every row carrying a date raised a hard error, in every timezone and on both input kinds, and the shape-based fallback for a renamed date column could never match either. Genuine XLSX date cells are now rendered from their components as ISO.
FixTimestamps silently truncatedA cell carrying a real time of day lost it: a 14:30 expiry exported as a bare date. The time is now preserved.

A detail worth recording. The serial-to-date conversion carries a sub-minute per-zone skew, because the library builds its epoch from a pre-1900 date and zones then sat on odd historical offsets. In one zone a 2026-04-12 cell lands on 23:59:50 the day before. Reading the components naively would have lost a whole day to ten seconds, so the value is rounded to the nearest minute first.

Verification: seven timezones spanning UTC-10 to UTC+14, against both CSV and XLSX inputs, with date-related errors going from four per four-row file to zero in all fourteen combinations.

Scope note

The original report of this defect over-generalised: it described the shift as affecting all exports. It affects CSV inputs only. Date cells in real XLSX exports were never shifted, because their display value is formatted from the stored serial rather than from a timestamp. The format fault, by contrast, affected both input kinds in every timezone.

v3.1: Two Output Columns Written Empty

Release Date: September 2026 · Status: Released

Background

Blade Chamber and Chord (%) appeared in every export with correct headers and no values beneath them, for any dataset that supplied them.

Changes

v3.1: Two Output Columns Written Empty
TypeFeature / FixDescription
Fix (bug 12)Two output columns wrote empty cells under correct headersThe alias map deliberately normalises Blade Chamber to BladeChamber and Chord (%) to Chord(%) on ingestion. The export then looked those values up by the output header text, which retains the space, so both lookups missed and both cells were written empty. The values were read correctly, matched correctly, validated correctly, and then not written. Fixed by pointing the export's source key at the canonical field name; the header text itself is unchanged, so anything downstream matching on it is unaffected.

Why it went unnoticed. There was no signal of any kind: no error, no warning, no Manual Review flag. Validation reads the value under its canonical name, where it is present and correct, so the field passes. Only the write missed. In the export the result is indistinguishable from a dataset that never supplied the column. This is the failure class already named at v2.4 — an unmapped field loses its values silently — but one link further down the chain: there the field signature was missing, here the signature works and the output lookup key is wrong.

Audit. All 39 output columns were checked for the same mismatch. Three other headers are not canonical field names: Date, which has a working bridge, and Action and Rule, which have no input field at all and are intentionally blank. These two were the whole set.

Known Issues at Release

v3.1.1: Export Column Width Realignment

Release Date: September 2026 · Status: Released

Background

The exported Damages Report set 38 column widths for 39 columns.

Changes

v3.1.1: Export Column Width Realignment
TypeFeature / FixDescription
Fix (bug 13)Column widths shifted one position from column E onwardThe width list was authored against the pre-v2.5 layout. The v2.5 split of Asset into Asset, Turbine Serial Number and Asset Serial Number inserted a column at position 5 and the list was never realigned, so every column from E onward wore its right-hand neighbour's width and the last column had none. This was not a missing final entry: a single-letter column rendered 28 wide, a two-character one 26, and a short code 40, while a 36-character identifier was squeezed to 10. Fixed by inserting the one missing entry, which realigns everything after it.
FixTwo field descriptions misrendered a company nameThe same casing error corrected in the output headers at v2.7.1, in two display-only field descriptions. No occurrence of the misrendered form now remains anywhere in the tool.

Verification: the two candidate readings were scored against the widest value each column can actually hold. The shipped alignment mis-sized 24 of 39 columns; the shifted reading, 14. Every implausible width resolves under the shift, which is what identified it.

v3.1.2 to v3.1.4: Column Width Fitting

Release Date: September 2026 · Status: Released

Background

With the alignment corrected, the widths themselves were still those authored for an earlier schema.

Changes

v3.1.2 to v3.1.4: Column Width Fitting
TypeFeature / FixDescription
Change (v3.1.2)Asset column narrowed28 to 8. The old width suited the pre-v2.5 schema, where the column held a full label rather than a single blade letter.
Change (v3.1.3)Widths fitted to content, 14 columnsFitted to the widest value each column can actually hold. For the nine conversion-driven columns that maximum is exact, computed from the conversion tables themselves. Columns whose content is free text the tool never sees were left alone rather than guessed at. A first pass changed 28 of 39 columns, but a third of those were single-character adjustments to columns that already fitted, so the rule was tightened to touch only widths that are genuinely deficient or oversized by more than ten.
Change (v3.1.4)Input Source Component set to an exact fitThe one column whose longest real value exceeds the general 45 ceiling. Raised to 51 by deliberate exception: it is the lookup key the Platform A and Platform B formulas read, and a clipped key is the first thing anyone checks when a lookup misses.

Verification: every conversion-driven column now seats its widest possible value with no clipping. Across all three releases the exported cell data is byte-identical; only the width declarations change.

Bug Index, v2.2 to v3.1.4

Thirteen defects were found and fixed across this range. Seven carry numbers in the internal change log; the rest were recorded without one and are numbered here for completeness.

Bug Index, v2.2 to v3.1.4
#VersionDefectRoot cause class
1v2.3Bare-letter blade values not extractedPattern too narrow for real input variation
2v2.3Duplicate Component column collisionAmbiguous match with no tiebreaker
3v2.3Duplicate Type column collisionAmbiguous match with no tiebreaker
4v2.4Format B export produced bare row numbersFormula referenced a column absent in that format
5v2.4Derived component doubledTransformed value read back as though raw
6v2.4Element section polluted by Blade Side rowsLookup array contents misfiled
7v2.7Ampersands double-encoded in URLsLibrary decodes on read differently than it encodes on write
8v2.6Literal "None" leaking into outputSentinel value not normalized at ingestion
9v2.7.1Four derived output headers misrenderedCopy error propagated by duplication, never by a matching consumer
10v3.0CSV dates shifted back one day west of UTCLibrary formats a UTC-midnight value with local accessors
11v3.0Every dated row failed its own date-format checkDisplay-formatted value used where the underlying value was required
12v3.1Two output columns wrote empty cells under correct headersExport keyed its lookup on header text, not canonical field name
13v3.1.1Column widths shifted one position from column E onwardPositional list never realigned after a column was inserted at v2.5

The pattern worth noting across them. Four of the first eight (1, 2, 3, 8) are the same class of failure: the tool assumed input data was more uniform than it is. Two more (4, 5) come from the derivation pipeline transforming a value and then reading it back as though untouched. Only bug 7 originates outside the tool's own logic. Every one of the first eight surfaced through contact with real data rather than through review, which is the argument for validating against genuine delivered files rather than reconstructed examples.

The later five sharpen a different point: silence. Bugs 9, 12 and 13 all produced output that looked plausible. A misrendered header, an empty cell under a correct header, and a column sized for its neighbour all render as a normal-looking spreadsheet, and none raises an error. Bug 12 is the starkest — the value is read, matched and validated correctly, and only the write misses, so the export is indistinguishable from a dataset that never supplied the column. Bug 11 is the opposite and was louder than it looked: it raised a hard error on every dated row in every timezone, which is the kind of noise that gets worked around rather than investigated. Three of the five (12, 13, and the shift in 11) trace to a positional or naming assumption left behind when a schema changed underneath it, which is the argument for checking the fixed-layout artefacts — output column lists, width arrays, lookup keys — whenever a column is inserted.

Archive note: v3.0 to v3.1.3 working files are reconstructions

Recorded 2026-09-18.

The working files for v3.0, v3.1, v3.1.1, v3.1.2 and v3.1.3 were not retained when those releases were made. Each release was produced by renaming the previous working file rather than copying it, so at any moment only the newest build existed on disk. The gap was noticed when the intermediate builds were called for.

They have been reconstructed and archived. The method was to replay each change forward from the retained v2.7.1 working file, in the order the changes were originally made, rather than to unpick them backward from v3.1.4 — a backward reconstruction produces files that cannot be checked against anything.

What validates them. Replaying every step lands on a v3.1.4 working file that is byte-for-byte identical to the real one, SHA-256 c37973f8…. Since the endpoint reproduces exactly, each intermediate state on the path to it is also correct. Independently, every reconstructed build was run through the export path and shows exactly the defect profile its release entry describes and no other: v3.0 still writes two columns empty, the width count first reaches one-per-column at v3.1.1, and the Input Source Component width moves 26 → 32 → 45 → 51 across the releases that changed it. Each build differs from its predecessor by that release's change alone.

What is not identical. These are faithful reconstructions of the file contents, not the original files. Their filesystem timestamps are the reconstruction date, not the original build dates. Anything relying on file modification time to date a build should treat v3.0 to v3.1.3 as undated and use this document instead.

Practice change. Releases are now produced by copying the working file rather than renaming it, so each version persists on its own.

Deployment

Deployment
PropertyDetail
DistributionShared Google Drive folder: download and open in any modern browser
DependenciesSheetJS (XLSX library) loaded from CDN on first use
Browser supportChrome, Edge, Firefox, Safari
Data privacyAll processing client-side. No data uploaded or transmitted.
File formatsCSV (UTF-8), XLSX, XLS
Typical dataset size50 to 500 rows per upload; tested up to ~400 rows
OutputXLSX (two-tab working document) + optional CSV validation report

Anomaly Upload Validator · Internal Use Only · v3.1.4 · September 2026

← Back to the Anomaly Upload Validator case study