# Audit CSV structure before constructing dictionaries

Use this when an agent receives CSV and needs to know whether records fit the chosen structure. A duplicate header can overwrite a value during dictionary conversion; a quoted newline can make a physical line count look like a record count.

Download and extract https://execution-evidence-lab.tuned-drake-1114.chatgpt.site/resources/csv-shape-audit/bundle.zip. Python 3 standard library only. No network calls, file rewrites, type inference, or formula execution.

## Run

In a POSIX-compatible shell:

```sh
python check.py < example.csv
python check.py --delimiter ';' < your-semicolon-file.csv
python check.py --delimiter tab --no-header < your-headerless-file.tsv
python test.py -v
```

`example.expected.json` is the recorded result for the included synthetic fixture. `verification.json` records executed tests, runtime, time, and hashes. Scripts read standard input and write diagnostics to standard output.

## Explicit interpretation

The default is comma-separated UTF-8, double-quote quoting with doubled embedded quotes, and the first record as the header. A leading UTF-8 BOM is accepted and removed only for decoding. Alternative delimiters are tab, semicolon, and pipe. Dialects and headers are not guessed.

Header names must be nonempty and unique under exact string equality. A whitespace-only name fails, but valid names are not trimmed or normalized. With `--no-header`, the first data record establishes the expected width. Every later record must have that width. Empty files and blank records are reported; a quoted empty field is a field, not a blank record. Header-only files are allowed and have zero data rows.

The audit returns the chosen dialect and header policy, raw header strings, column count, parsed data-row count, consumed physical-line count, `error_count`, up to 100 diagnostics, and `errors_truncated`. Row-width errors distinguish the logical record from its physical start/end lines. Counts on a failed parse describe only what was consumed before the error.

Exit 0 means the input fits the selected structure; exit 1 means a failed audit. Limits: 1 MiB total input, 65,536 characters per field, and 100 returned diagnostics. Total diagnostic count is retained.

## What a pass does not mean

This is a structure audit under Python's explicit CSV dialect, **not a complete RFC CSV validator**. Even `strict=True` accepts a quote embedded in an unquoted field; the fixture suite documents that behavior. A consistently wrong delimiter may still produce a valid one-column file. Confirm the delimiter and expected schema independently.

No semantic checks, schema matching, encoding guesses, sanitization, repairs, or spreadsheet-formula filtering are performed. Leading-zero identifiers remain strings. Do not interpret a pass as proof that a spreadsheet or downstream parser will behave identically. Tested runtime details are in `verification.json`; other versions are unverified.

Primary source checked 2026-09-10: [Python CSV reader, dialects, and line counting](https://docs.python.org/3/library/csv.html). Original utility code and fixtures: MIT, see `LICENSE`.
