Before anything can be compared, the file has to be read the same way twice. Most of the surprises in a recurring handoff happen here, in the ten seconds before anyone looks at a column list.

Delimiters are detected, not assumed

The workbench considers the comma, tab, semicolon, and pipe. It parses the header line with each candidate and prefers the one that yields the most columns. If two candidates tie, it refuses to guess and asks you to choose, because a silently wrong delimiter produces a profile that looks plausible and is entirely fictional.

Semicolon files are common wherever the decimal separator is a comma, and pipe-delimited files are common out of older warehouse systems. Both are first-class here. Where the producer documents the delimiter, set it explicitly on the intake control rather than relying on detection at all: detection is a convenience for exploration, not a contract.

Encoding is a choice you make, not a guess the tool makes

UTF-8, UTF-16LE and UTF-16BE are supported and decoded strictly. A byte sequence that is not valid in the encoding you chose is rejected with a message saying so, rather than being replaced with substitution characters. That matters because a wrong encoding corrupts header names first, and a corrupted header name looks exactly like a renamed column when you compare two months side by side.

Strict parsing is a feature

The parser refuses a file rather than reshaping it. It rejects a row whose field count does not match the header, a quote that opens in the middle of a field, text after a closing quote, a file that ends inside a quoted field, an empty header, and a duplicate header after case folding. It also refuses reserved object keys as header names.

Every rejection names the row. The alternative, quietly padding a short row or dropping a long one, would put invented values into the very evidence you are about to hand a downstream owner. If a real export legitimately contains such rows, that is itself a finding worth taking to the producer.

All-blank rows are counted

A data row where every field is empty is a real row. It is retained, it counts toward the row total, and it raises the blank rate of every column, because a candidate export that gained five hundred empty rows is a change the recipient needs to hear about.

What type inference means here

Each column is classified per value into empty, boolean, integer, number, date, datetime, or string, and the column is given the type that dominates, with a confidence figure attached. Dates are round-trip checked, so an impossible calendar date does not pass as a date.

This is observed evidence about the rows that were profiled, and nothing more. It is not a declared schema, it does not describe values that did not appear this month, and it says nothing about meaning. A column that profiles as an integer may be an identifier that must never be arithmetic. Inference finds questions worth asking; the answers come from the producer's documentation and from the people who own the consumers.

Bounds are enforced

File size, row count, column count, and total parsed cells all have declared limits, and exceeding one rejects the intake with the specific limit named. Nothing is truncated silently.