# EDA Desk > Drop a CSV or TSV you are about to model, name its split, entity, group and time columns, and find > out whether the train/validation/test split can support an honest held-out score. A free in-browser > audit runs the exploratory-data-analysis agent skill's own tools; two metered lanes do the judgement > from aggregates only. URL: https://eda-desk.skillsafe.ai/ API: https://eda-desk.skillsafe.ai/api.html Tokens: https://eda-desk.skillsafe.ai/tokens.html Model: gpt-terra (the balanced GPT tier alias on SkillSafe) Source skill: @k-dense-ai/exploratory-data-analysis (k-dense-ai/scientific-agent-skills, MIT) - bounded, redacted, local exploratory analysis of scientific data files. ## What runs free, in the browser JavaScript ports of the skill's three standard-library CSV/TSV tools, with the same JSON output as the Python (checked on fuzzed files against CPython 3.12; see NOTICE.txt): - tabular_profile.py - inferred kind, missingness, distinct counts, numeric aggregates and duplicate rows per column; quantiles from a deterministic bounded sample of 512 values. - missingness_leakage_audit.py - missingness overall, by split and by group; counts of entity values, group values, rows identical apart from the split, and split time ranges that appear in more than one split; rows with no split; time values that are not ISO-8601. - distribution_sensitivity.py - mean and SD against median, IQR and MAD; values outside the 1.5 IQR fences; 10% trimmed and winsorized means; moment skewness raw and after log1p (or signed log1p). No tool prints a raw value. Cells, entity ids and (by default) column names become BLAKE2s tokens; --reveal-identifiers shows sanitized column names but never split, group or entity values. The page adds its own numbered flags (labelled as the page's) and a status: leakage_flagged, not_assessed, review_before_modeling or no_flags. ## Free fixes and the re-check loop All in the browser, each applied only on a click: - Resplit without the overlap - when entities, groups or identical rows sit in more than one split, the page moves every entity (or group) into one split as a whole, chosen by a hash of its value against the current splits' row shares, keeps the split labels, audits the result and offers it as a CSV. It ignores time; for forward-in-time prediction, split by time instead. - What changed since the last audit - the next audit of a table with the same header and roles (the fixed file) lists the counts that moved: entities in more than one split 31 -> 0, flags 8 -> 6. Counts only, kept in this browser per signed-in person and deleted at sign-out. - Semicolon exports with decimal commas, trailing delimiters and blank lines are rewritten as a plain CSV, with every change listed. - Text inside numeric columns ("NA", "<0.5", "nan") is offered as a missing code. ## The two metered lanes (field `task`) - split - judges whether the split supports an honest held-out score. Status resplit_required, usable_with_fixes or usable_as_is; a response to every flag; leak findings with the numbers they rest on; a split plan (unit, method such as group_shuffle_split or time_forward, hold-out, steps); preprocessing order (fit on train only); and a pandas/scikit-learn snippet. - report - drafts the EDA report the skill's report template asks for: scope, structure, split, schema, missingness, distributions, transformations, limitations, key findings with alternatives and confirmation needed, and data-dictionary requests. Status proceed_to_modeling, proceed_with_caveats or do_not_model_yet. It can take the split review as input. Both read only the aggregates, the flags and what the user types. Every reply is reconciled in the browser: all flags answered, a status no looser than the evidence (an entity in two splits always means resplit_required), every cited number present in what was sent, every token known, no causal wording. ## Limits, stated plainly - A flag is a diagnostic; "not detected" is within the scanned rows and roles only. - The skewness fields depend on the platform's pow and log1p, so CPython's own output differs between operating systems in the last digit or two; the page computes them correctly rounded. - Time parsing follows CPython 3.12's datetime.fromisoformat (3.14 accepts "24:00" and 3.12 does not). - Partial scans are named: a file cut at --max-rows says so on the page and in every download name; columns past the distribution audit's first 64, and a leakage audit that hit its key limit, are flagged. - Long notes sent to the model keep their start and end; the middle is cut and marked. - Nothing here is causal, confirmatory or a certification of data quality. ## Citation Kassis, T., Agarwal, V., He, Y., Patel, D., & Brueckner, A. M. (2026). Scientific Agent Skills: A Library of Procedural Knowledge for Research Agents. arXiv:2609.00065. https://doi.org/10.48550/arXiv.2609.00065