openai/analyze-data-quality
Assess whether structured data, query results, dashboards, or analytical evidence are trustworthy enough to use. Use when the task is to check data quality, reconcile conflicting sources or metric definitions, or decide whether evidence is safe to cite.
npx skills add https://github.com/openai/role-specific-plugins --skill analyze-data-quality
Use $design-kpis when the work is to define or redesign a KPI framework, metric definition, guardrail, or target rather than checking whether existing data is trustworthy.
Use $validate-data when the work is to QA an analysis, chart, report, or recommendation rather than investigate the underlying data.
Assess whether a dataset is trustworthy enough for analysis, modeling,
dashboards, experiments, or downstream pipelines. Start with the intended use and grain, run the highest-value checks for the data shape, and report concrete evidence, analytical risk, likely causes, and the smallest useful remediation or automated test.
Establish what the dataset represents, the intended unit of analysis, the downstream use, whether the user cares about raw ingestion quality,
transformed-model quality, or both, and the comparison baseline such as prior weeks, prior schema, or a trusted reference table. Identify expected grain,
primary keys or candidate keys, important date columns, timezone assumptions,
domain rules, allowed values, and business thresholds. If context is missing,
infer cautiously and label assumptions.
When checks require SQL or Python, default to a companion notebook so the user can inspect the exact code behind the findings. Use $jupyter-notebooks when a dedicated notebook scaffold or refactor workflow would help. For queryable tables, use ~~structured_data to confirm schema, grain, sample rows, and query rules through the relevant source connector before heavier checks. Use ~~operations_logs for freshness and lineage when those checks matter.
Start with row count, column count, column names and types, candidate keys,
duplicate rates on likely identifiers, min/max timestamps for relevant date columns, null rates, distinct counts for likely categorical columns, and basic numeric summaries for measure columns. Confirm grain before interpreting anomalies; many apparent quality problems are mixed-grain data,
partial backfills, late-arriving data, or duplicated joins.
Select checks that match the dataset and task. Default to the most relevant checks across completeness, uniqueness, validity, consistency, integrity,
timeliness, volume, and shape. Compare rates, not just counts, and segment by time, source, country, platform, model version, or other key dimensions when that helps distinguish real issues from expected variation.
Adapt the checks to the data shape:
coverage gaps, and abrupt event-mix changes after releases.
changes without corresponding timestamps, and unexpected churn in reference
values.
quantity, join blowups to dimensions, and late-arriving or partially loaded
partitions.
sparsity spikes, range shifts after model or feature-store changes, and
class-label drift.
expectation, exposure without assignment, and events before assignment
timestamp.
Prioritize temporal diagnostics when the user mentions "after X date",
"suddenly", "recently", or "only started appearing". Check first-seen dates,
last-seen dates, daily or weekly null-rate trends, duplicate-rate trends, row count trends, category-share shifts, distribution drift, and change points around launches, migrations, incidents, model changes, or backfills.
Tie each issue to the downstream risk: broken trusted analysis, biased decisions, broken joins, stale dashboards, incorrect experiments, leakage,
unreliable model features, or misleading segments. When possible, identify whether the issue is isolated to a source, segment, partition, time window,
release, migration, backfill, or upstream pipeline change.
Recommend the smallest set of follow-up fixes, monitoring, or automated tests that would materially reduce risk. Suggest automation only when the rule is stable and worth maintaining. Include or save the notebook/query path when code produced the findings.
enums, country codes, and timestamps; range checks for measures, percentages,
counts, and dates; allowed-values checks for controlled vocabularies.
share-of-total drift for major categories, and new or disappeared categories.
casing, formatting, or late updates. Report count, share of affected rows,
duplicated keys, and whether duplication is isolated to a time range, source,
or segment.
'', 'unknown', 'n/a', 0, or -1.impossible values, values outside allowed sets, and cross-field contradictions such as is_cancelled = false with a non-null cancelled_at.
lag on important date columns, added/removed/retyped columns, and shifts in sparsity or cardinality that suggest upstream changes.
or IQR before defaulting to z-scores. Check sudden changes in mean, median,
variance, zero rate, category share, and long-tail behavior.
category drift in a core dimension, invalid business-rule values, leakage, or severe join coverage loss.
monitoring, or owner follow-up.
Do not dump raw profiling output without interpretation. Tie each finding to an analytical risk and likely impact.
freshness thresholds, and seasonality-aware row-count or volume bounds.
For stakeholder-facing data-quality work, pass the completed findings to $build-report by default so the runtime produces an MCP app or HTML report. Do not stop at profiling output, a notebook, or chat-only findings unless the user explicitly requested a quick inline answer or another primary artifact. The structure below defines the report content.
Structure the response with:
For each finding, include:
When code was used, include or save a notebook containing the key SQL and Python checks and make the notebook path easy to find.
experiment, migration, incident, model change, or backfill.
sample rows, chart outputs, and calculation notes.
Take openai/analyze-data-quality from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.