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 | Release Date | Status | Key Milestone |
|---|---|---|---|
| v1.0 | May 2026 | Released | Core validator, field presence + format checks |
| v1.1 | May 2026 | Released | Three-tier status system: Error / Check Internally / Warning |
| v1.2 | May 2026 | Released | Blade Side expanded values; Serial Number made optional |
| v2.0 | May 2026 | Released | Full conversion engine + XLSX export with live formulas |
| v2.1 | May 2026 | Released | Multi-format support (Format A and Format B); ISBLANK bug fix |
| v2.2 | May 2026 | Released | Bulk resolution of Manual Review flags |
| v2.3 | May 2026 | Released | Content-based column matcher; header detection; 3 bugs fixed |
| v2.4 | June 2026 | Released | Pass-through field signatures; sheet order; 3 bugs fixed |
| v2.5 | June 2026 | Released | Output schema change: Asset, Turbine SN, Asset SN split |
| v2.6 | June 2026 | Released | Clickable image hyperlinks in the exported report |
| v2.7 | June 2026 | Released | URL entity double-encoding fix |
| v2.7.1 | September 2026 | Released | Four derived output header names corrected; LIM-07 closed |
| v3.0 | September 2026 | Released | Date handling: timezone shift and format fault corrected |
| v3.1 | September 2026 | Released | Two output columns that wrote empty cells under correct headers |
| v3.1.1 | September 2026 | Released | Export column widths realigned; two field descriptions corrected |
| v3.1.2 | September 2026 | Released | Asset column width reduced to suit the v2.5 schema |
| v3.1.3 | September 2026 | Released | Column widths fitted to content across 14 columns |
| v3.1.4 | September 2026 | Released | Input 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
| Type | Feature / Fix | Description |
| Feature | File ingestion | Drag-and-drop or browse for CSV / XLSX. Parsed client-side via SheetJS, with no data transmitted externally. |
| Feature | Column-level validation | Checks all 19 required column headers present (case-sensitive). Flags missing columns with description. |
| Feature | Row-level validation | Validates every required field: presence, format (date, severity range, Yes/No, blade side codes, coordinate pairs, numerics). |
| Feature | Compliance score | Percentage clean rows with color indicator (green 80% or above, amber 50% or above, red below 50%). |
| Feature | Issues table | Tabular view: Row #, Anomaly ID, Field, Status, Detail. |
| Feature | Filter tabs | Filter by All / Errors / Warnings. |
| Feature | Validation report export | Download issues as dated CSV. |
| Feature | Dataset summary | Total anomaly count, unique turbine count, unique site count with per-site breakdown. |
Known Issues at Release
- Serial Number treated as required, demoted to conditional in v1.2.
- Blade Side validation limited to two-character codes only.
- No conversion logic; field values validated as-is.
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
| Type | Feature / Fix | Description |
| Feature | Check Internally status | New third status (blue) for Asset and Coordinates when empty. Rows excluded from compliance score. |
| Enhancement | Compliance score denominator | Score = clean rows / (total - check-internally rows). |
| Enhancement | Check Internally filter tab | Dedicated filter tab added to issues table. |
| Enhancement | CSV export labels | Three-label Status column: Error / Check Internally / Warning. |
| Enhancement | Summary stats card | Fifth 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
| Type | Feature / Fix | Description |
| Enhancement | Blade Side expanded values | Accepts full names: Value 1, Value 2, Value 3, Value 4 alongside Code 1/Code 2/Code 3/Code 4 codes. Case-insensitive. |
| Enhancement | Serial Number made optional | Serial Number demoted from Required to Conditional. Empty value raises no flag. |
| Enhancement | Field counts corrected | Required 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
| Type | Feature / Fix | Description |
| Feature | Input Source Component derivation | Concatenates Component + Material (if present) using LEN() guard against empty strings. |
| Feature | Input Source Damage Type derivation | Concatenates Type + Subtype (if present) using LEN() guard. |
| Feature | Element conversion | Three-column output: Input Source Component to Platform A Element and Platform B Element via lookup. |
| Feature | Anomaly Type conversion | Three-column output: Input Source Damage Type to Platform A Anomaly Type and Platform B Anomaly Type via lookup. |
| Feature | Blade Side conversion | Blade Side to Platform A Blade Side and Platform B Blade Side. |
| Feature | Manual Review status | Amber status when concatenated value not in conversion table. Original value preserved. Blocks XLSX export until resolved. |
| Feature | Human-in-the-loop resolution | Dropdown on each Manual Review row. Export unlocks when all resolved. |
| Feature | Export Converted XLSX | Two-tab output: Damages Report (all columns, live VLOOKUPs) + Conversions (editable mapping table for Engineering). |
| Feature | Live VLOOKUP formulas | Derived columns reference Conversions tab. Engineering adds rows; formulas update automatically. |
| Feature | Column normalisation | Alias map handles variants: Date to Inspection Date, Turbine Serial Number to Serial Number, Links to Source Images, etc. |
| Enhancement | Floating point cleanup | Numeric fields cleaned of floating-point noise on import. |
| Enhancement | Blade letter extraction | Blade field populated from Asset column when empty. |
Known Issues at Release
- VLOOKUP row ranges hardcoded in exported XLSX. Engineering adding rows beyond existing ranges requires manual formula updates.
- ISBLANK() formula limitation, fixed in v2.1.
- Single dataset format supported at release (Format A structure). Multi-format added in v2.1.
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
| Type | Feature / Fix | Description |
| Fix | ISBLANK to LEN() fix | Excel formulas changed from IF(ISBLANK(Subtype),...) to IF(LEN(Subtype)=0,...). Handles both truly blank and empty-string cells. |
| Fix | Format B Element column | Detects whether Material column is present. Falls back to Element column as component suffix if absent. |
| Fix | Format B Anomaly Type column | Reads Type column when present; falls back to Anomaly Type column when absent. |
| Fix | Blade field normalisation | Format B stores 'Blade A' in Blade column. Tool strips label prefix and retains letter for both formats. |
| Enhancement | Column alias expansion | COL_ALIASES extended with additional pass-through variants. |
Datasets Validated
- Format A, Input Source export (Component + Material, Type + Subtype structure)
- Format B, Input Source export (Component + Element, Anomaly Type + Subtype structure)
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
| Type | Feature / Fix | Description |
|---|---|---|
| Feature | Bulk resolution | Multiple unmapped values resolved at once through dropdown selection rather than row by row. |
| Unchanged | Export gate | Export 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
| Type | Feature / Fix | Description |
| Feature | Content-based column matcher | Two 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. |
| Feature | Automatic header-row detection | Up to 25 rows of metadata preamble above the header are scanned and skipped. |
| Feature | Priority-ordered alias matching | A more specific alias wins over a general one for the same canonical field. |
| Feature | Duplicate-name disambiguation | Where two columns share a name, the closer data-shape match wins. |
| Feature | Distinct-value tiebreaker | Where 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. |
| Feature | View detected columns | Collapsible confirmation panel in the file-info line showing which input column was bound to each canonical field. |
| Fix (bug 1) | Bare-letter blade extraction | The 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 collision | A 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 collision | The 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
| Type | Feature / Fix | Description |
| Fix | Missing field signatures | Signatures added for Propagation Type, OpSeverity, Monitoring Recommendation and Tasks. These fields were already defined and already expected; they were simply never bound. |
| Fix | Inspection Date bridge | The export cell writer now bridges the input field name to the output field name, which differ. |
| Enhancement | Sheet order | Damages Report moved to the first sheet position and Conversions to the second, matching the convention of amended files received from Engineering. |
| Enhancement | Conversion table key added | One 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 numbers | Where 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 concatenation | After 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 rows | Four Blade Side entries were wrongly embedded at the top of the Element conversion array. Removed, with section-range arithmetic recalculating automatically. |
Decisions
- Formulas reference the output slots, never the raw input columns. The output Material slot carries the effective suffix, Material for Format A and Element for Format B. The output Type slot carries the damage base, Type for Format A and Anomaly Type for Format B. One formula path therefore serves both input formats.
- Any raw input value the export needs is read from the untouched input row, never from the working row. Row processing mutates the working row during derivation, so reading a value back from it after processing returns the transformed value. This is the general rule behind bug 5 and it applies to every future export field.
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
| Type | Feature / Fix | Description |
| Schema | Output column D, Asset | Now carries the blade letter, A, B or C. |
| Schema | Output column E, Turbine Serial Number | New. Carries the value previously written to the output Asset column. |
| Schema | Output column F, Asset Serial Number | New. 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
- A column was inserted, so every output column to the right of F has shifted by one position. Formula column references and any downstream consumer matching on column position are affected. See the data dictionary's open verification items.
- Semantic mismatch on the input side, accepted deliberately. The matcher's canonical Asset field still binds by name to the input Asset column, which now carries turbine numbers. The field is therefore named Asset and means turbine number on the way in, while meaning blade letter on the way out. Renaming it was judged a larger change than this release warranted.
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
| Type | Feature / Fix | Description |
|---|---|---|
| Feature | Hyperlink attachment | A 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. |
| Correctness | Non-URL values left alone | Source 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 output | Some 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
| Type | Feature / Fix | Description |
|---|---|---|
| Fix (bug 7) | Ampersands double-encoded in URLs | When the XLSX library reads a hyperlink from an input file it returns the URL with XML entities still encoded, so an ampersand arrives as & rather than as &. Passing that value back to the same library to write encodes it a second time, producing &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
- Image links expire, and the tool does not warn about it. The signed URLs are time-limited by the source system, typically around a 30 day window, after which the storage provider returns the same not-found error this release fixed. That is an upstream constraint rather than a tool defect, and the two failures are indistinguishable to a user clicking a dead link. A file exported and then left unprocessed past the window will produce a report whose links fail silently. An expiry warning at ingest is a candidate for a future 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
| Type | Feature / Fix | Description |
|---|---|---|
| Fix (bug 9) | Four derived output headers misrendered | Columns 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
- Exports produced before this release still carry the old headers. A consumer matching those files by header string still has to match two spellings of one name to catch all three of its columns.
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
| Type | Feature / Fix | Description |
|---|---|---|
| Fix (bug 10) | Dates from CSV shifted back one day west of UTC | The 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 check | The 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. |
| Fix | Timestamps silently truncated | A 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
| Type | Feature / Fix | Description |
|---|---|---|
| Fix (bug 12) | Two output columns wrote empty cells under correct headers | The 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
- Exports produced before this release cannot be repaired from the converted copy. The values are not in it. Any file needing those two columns has to be re-run from the original Input Source export.
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
| Type | Feature / Fix | Description |
|---|---|---|
| Fix (bug 13) | Column widths shifted one position from column E onward | The 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. |
| Fix | Two field descriptions misrendered a company name | The 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
| Type | Feature / Fix | Description |
|---|---|---|
| Change (v3.1.2) | Asset column narrowed | 28 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 columns | Fitted 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 fit | The 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.
| # | Version | Defect | Root cause class |
|---|---|---|---|
| 1 | v2.3 | Bare-letter blade values not extracted | Pattern too narrow for real input variation |
| 2 | v2.3 | Duplicate Component column collision | Ambiguous match with no tiebreaker |
| 3 | v2.3 | Duplicate Type column collision | Ambiguous match with no tiebreaker |
| 4 | v2.4 | Format B export produced bare row numbers | Formula referenced a column absent in that format |
| 5 | v2.4 | Derived component doubled | Transformed value read back as though raw |
| 6 | v2.4 | Element section polluted by Blade Side rows | Lookup array contents misfiled |
| 7 | v2.7 | Ampersands double-encoded in URLs | Library decodes on read differently than it encodes on write |
| 8 | v2.6 | Literal "None" leaking into output | Sentinel value not normalized at ingestion |
| 9 | v2.7.1 | Four derived output headers misrendered | Copy error propagated by duplication, never by a matching consumer |
| 10 | v3.0 | CSV dates shifted back one day west of UTC | Library formats a UTC-midnight value with local accessors |
| 11 | v3.0 | Every dated row failed its own date-format check | Display-formatted value used where the underlying value was required |
| 12 | v3.1 | Two output columns wrote empty cells under correct headers | Export keyed its lookup on header text, not canonical field name |
| 13 | v3.1.1 | Column widths shifted one position from column E onward | Positional 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
| Property | Detail |
|---|---|
| Distribution | Shared Google Drive folder: download and open in any modern browser |
| Dependencies | SheetJS (XLSX library) loaded from CDN on first use |
| Browser support | Chrome, Edge, Firefox, Safari |
| Data privacy | All processing client-side. No data uploaded or transmitted. |
| File formats | CSV (UTF-8), XLSX, XLS |
| Typical dataset size | 50 to 500 rows per upload; tested up to ~400 rows |
| Output | XLSX (two-tab working document) + optional CSV validation report |
Anomaly Upload Validator · Internal Use Only · v3.1.4 · September 2026