Cheat sheets

Data Quality and Dataset Gates

Load and split data with a seed, repair CSV cells, gate rows on a contract, audit leaks and rehearse migrations.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Comparisons
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

What each gate builds#

FactorCSV repairContract gateSplit auditorMigration rehearsal
BuildsCleaned table and recipeAccepted and quarantine rowsLeak report per recordRehearsal receipt
Inputcsv text, aliases, date_columnsJSONL plus contract.json{train,test} or {records}Database, migration, rollback, invariants
Outputcleaned.csv, recipe.jsonaccepted.jsonl, quarantine.jsonlsplit-audit.jsonrehearsal.json, schema-diff.json
Pass signalNo pending cellspassed is trueusable is truerelease_ready is true
Gate exitNonzero on failureexit 1 rule, exit 2 inputexit 2 when unusableNonzero on failure
LimitSlash and ISO dates onlyNo semantic truthExact copies, not paraphrasesSQLite policy, not OS isolation

Run and grade#

CommandWhat it does
python3 scripts/project_test.py <project> --init <workspace>Makes a workspace. The first run fails
python3 scripts/project_test.py <project> --all --solution --strictChecks the reference solution
python3 cli.py samples/input.json --output demo-outputRuns CSV repair or migration rehearsal
python3 cli.py sample.csv --question "sum units by region" --output output/report.htmlAnswers a CSV question with a receipt
python3 cli.py samples/input.jsonl --contract samples/contract.json --output demo-outputSplits rows into accepted and quarantine
python3 cli.py samples/input.json --output split-audit.json --html split-audit.htmlAudits a train and test split
python3 cli.py --train train.jsonl --test test.jsonl --check --output split-audit.jsonAudits JSONL partitions in CI
python code/data_utils.pyLoads, converts, splits and fingerprints a dataset

Defaults and limits#

SettingDefaultNote
--limit100Result rows, at most 1000
max_steps100000SQLite instruction budget
load_csv rows10000Under 2 MB, at most 50 columns
--seedcourseGroup hash seed for --split
Contract rows100000API input cap
SQL deadlinetwo-secondBounds statements, not backups
make_splits seed42Train 0.8, validation 0.1
Local storage10 GBUse cloud storage above it

Errors and fixes#

SymptomCauseFix
"ragged row"A row has the wrong cell countFix the source row
Pending "ambiguous date"Both parts are 12 or less and differGive an ISO date in decisions
"stale review"Table or recipe changed after reviewReview the new preview again
"Query rejected: "SQL left the read boundaryWrite one SELECT over data
"Aggregate column must contain finite numeric values"Column is TEXTAggregate a REAL column
Contract --check exits 1Rows are in quarantineRead review.html. Decide on rows apart
Split usable is falseContent or group leakSplit by group with --split
release_ready is falseRollback is not exactWrite rollback SQL that restores rows

Read-only CSV question#

questionschemaSQLSQLsha256 and SQLstoresample.csvUTF-8, under 2 MBprocessload_csvREAL or TEXT percolumnprocessplan_questionsmall questiongrammarmodel--modelproposes SQL fromschemaprocessrun_queryauthorizer,query_only, budgetclientreport.htmlplus .json receiptquestionschemaSQLSQLsha256 and SQLstoresample.csvUTF-8, under 2 MBprocessload_csvREAL or TEXT percolumnprocessplan_questionsmall questiongrammarmodel--modelproposes SQL fromschemaprocessrun_queryauthorizer,query_only, budgetclientreport.htmlplus .json receipt

Migration rehearsal#

1snapshotopen the source read-only and back it up intomemory.2snapshotrecord schema, row counts, row-content SHA-256and sequences.3rehearseapply the migration to the in-memory copy only.4rehearsedeny ATTACH, DETACH, PRAGMA, virtual tables andfile functions.5test_rollbackrun migration and rollback on one disposablebackup.6reversibleno errors and the restored snapshot equalsbefore.7receiptcheck each invariant. release_ready needs all ofthem and rollback.

Split with a seed#

dataset = load_dataset("stanfordnlp/imdb", split="train")
split = dataset.train_test_split(test_size=0.2, seed=42)
train_val = split["train"].train_test_split(test_size=0.125, seed=42)
train_ds = train_val["train"]70 percent of all rows
val_ds = train_val["test"]10 percent
test_ds = split["test"]20 percent
dataset.to_parquet("imdb_train.parquet")best storage format
load_dataset("wikimedia/wikipedia", "20231101.en", split="train", streaming=True)

Project functions#

TaskCode
Profile CSV columnsprofile(text)
Preview cell changespreview(table, recipe)
Apply reviewed repairsrepair(table, recipe, decisions=None)
Check one recordrow_issues(row, contract)
Find duplicate groupsduplicate_rows(rows, contract)
Audit two partitionsaudit(train, test)
Split by group hashsplit_groups(records, test_fraction=0.2, seed='course')
Run a bounded readrun_query(data, sql, max_rows=100, max_steps=100000)

Version large files#

CommandWhat it does
git lfs track "*.safetensors"Stores the file outside git with a pointer
dvc add data/training_set.parquetMakes a small .dvc pointer file
dvc remote add -d myremote s3://my-bucket/dvc-storeSets the DVC remote
dvc pushUploads tracked data to the remote
snapshot_download("sentence-transformers/all-MiniLM-L6-v2")Caches a full model repo

Rules in code#

Recipe order
trim, then alias, then date for each column.
Changes
each change names row, column, before and after.
No coercion
Boolean true fails integer and number fields.
Duplicates
every colliding row is reported, the first one too.
Gate
a dataset passes with no quarantined rows and no dataset issues.
Fingerprint
NFKC, casefold and collapsed spaces, then SHA-256.
Group split
SHA-256 of seed and group over 2**256, below the fraction is test.
Formats
Parquet for storage, Arrow in memory, CSV and JSON to exchange.

Questions#

Does normalization catch paraphrases?
No. It finds exact normalized copies only.
Does rehearsal change the source database?
No. The source is never opened writable.
Does the model run its SQL freely?
No. SQLite authorization still controls execution.
Can I drop quarantined rows at once?
No. Partitions are evidence, not permission to discard.
Why set a seed?
The same seed produces the same split every time.

Tips#

  • Replay a recipe on another table with --recipe recipe.json.
  • Read cleaned.csv with csv.DictReader as the downstream consumer.
  • Wait for the gate command to finish before you load its outputs.
  • Keep the input beside the output so others can reproduce it.
  • Keep model weights out of git with .gitignore. Use DVC to reproduce runs.