method-data-qa skill
Profiles data columns and executes quality gates to validate extracts against SAP expectations before modeling or unblinding.
- GitHub stars
- 6
- Files
- 5
- Last commit
- Oct 31, 2026
- License
- MIT
- Allowed tools
- —
What does the method-data-qa skill do?
method-data-qa profiles data columns and executes quality gates to validate extracts against SAP expectations before modeling or unblinding.
Summary generated from the skill's SKILL.md.
About the method-data-qa skill
Data analysts and researchers use this skill to validate data extracts against Statistical Analysis Plan expectations before they begin modeling or unblinding. It acts as a formal quality gate that prevents downstream errors by inspecting column profiles, checking for missingness, identifying duplicates, and verifying data types. The tool can operate in two distinct modes: a pre-SAP mode that profiles columns to help draft a plan, and an SAP-aligned mode that compares actual data against declared variables and populations.
When an agent detects a new data wave or a potential drift in data shape, it can load this skill to produce a GO/NO-GO report. The process relies on files like analysis/sap.md for shape expectations and analysis/data-waves.md for provenance. It produces detailed markdown or HTML reports containing findings categorized as block, warn, info, or pass. The skill also includes strict PHI guards to ensure sensitive values are never echoed in reports, instead providing only aggregate counts and masked samples.
What an agent can do with it
- 1Profile data for SAP draftingInspect a dataset to understand its structure before a Statistical Analysis Plan has been written.
- 2Prevent modeling with bad dataAutomatically stop the data pipeline if critical integrity violations like incorrect key types are found.
Written from the skill's SKILL.md. Every use case is checked against a quote from it.
How to install the method-data-qa skill
Each command copies the skill folder into the client's skills directory. Restart the client or start a new session to load it.Install the method-data-qa skill in Plugin
/plugin marketplace add sajor2000/methodsmith /plugin install methodsmith@methodsmith
Install the method-data-qa skill in Claude Code
~/.claude/skills/method-data-qa/SKILL.md
$ npx degit sajor2000/methodsmith/plugins/methodsmith/skills/method-data-qa ~/.claude/skills/method-data-qaInstall the method-data-qa skill in Claude Code (project)
.claude/skills/method-data-qa/SKILL.md
$ npx degit sajor2000/methodsmith/plugins/methodsmith/skills/method-data-qa .claude/skills/method-data-qaInstall the method-data-qa skill in Codex
~/.agents/skills/method-data-qa/SKILL.md
$ npx degit sajor2000/methodsmith/plugins/methodsmith/skills/method-data-qa ~/.agents/skills/method-data-qaInstall the method-data-qa skill in Gemini CLI
~/.gemini/skills/method-data-qa/SKILL.md
$ npx degit sajor2000/methodsmith/plugins/methodsmith/skills/method-data-qa ~/.gemini/skills/method-data-qaInstall the method-data-qa skill in Claude.ai
npx degit sajor2000/methodsmith/plugins/methodsmith/skills/method-data-qa method-data-qa && zip -r method-data-qa.zip method-data-qa # claude.ai → Customize → Skills → + → Create skill → Upload a skill → method-data-qa.zip
SKILL.md
View on GitHubData Quality Assessment Gate
Skill Value
- Problem it solves: Analysis can start before grain, keys, missingness, duplicates, dates, and extract validity are understood.
- Use when: The user asks to inspect columns, validate a fresh extract, compare data to cohort/SAP expectations, or check readiness.
- Output: A data profile or GO/NO-GO QA report plus CE_DATA_PROFILE or data-wave handoff signal.
- Ask only if: Only for file paths, intended grain, key fields, or SAP/cohort links that cannot be inferred.
- Do not do: Do not certify SAP correctness or run modeling.
- Interaction: Check repo/config/chat evidence first. Ask one decision-changing question at a time; use the current harness's blocking question UI when available, otherwise present numbered choices and wait.
This skill formalizes the data-QA gate that exists between data extraction and SAP/modeling work. No SAP finalization, coding, or modeling runs until the available data columns and QA status are documented. A "fail" outcome blocks the pipeline; a "warn" outcome requires PI sign-off; a "pass" outcome unlocks the data lock + modeling phase. When the SAP does not exist yet, run in pre-SAP column profile mode and emit a data profile that method-plan uses to draft the SAP without inventing variables.
When This Skill Activates
- A new data wave or extract was recorded and downstream code expects to model it
- The SAP shape may have drifted from the data shape (analyst noticed column rename, type change, or value-set expansion)
- Before unblinding for confirmatory analysis (final QA pass against the locked SAP)
- After a re-extract following an EHR query fix
- Manual invocation via
method-data-qato spot-check a dataset
Prerequisites
-
A SAP exists at
analysis/sap.md(or specified via--sap) for full SAP-aligned QA. If no SAP exists yet, run pre-SAP column profile mode instead of stopping. -
A stack profile exists so
data_rootis known. If none exists, ask the user to run themethod-setupcommand (it is manual-invocation-only and cannot be loaded by the model), or ask them directly fordata_rootand proceed with that answer. -
The data extract is recorded in
analysis/data-waves.mdwith extract id, location, source, received date, row count when known, and a content hash when available. -
Sensitive-data boundary. Resolve
phi_environment.modein.methodsmith/config.local.yaml(worktree, then main checkout; legacycompliant: true=approved,compliant: false=schema-only,sensitive_data: false=no-sensitive-data; any schema-only signal wins; unreadable =schema-only).approvedorno-sensitive-data: proceed silently and never mention the boundary again.schema-only: headings, types, counts, and aggregates only; never open, print, or paste data values; run data-reading scripts asmethod-safe-run -- <command>(path in the guard's deny message); save results as aggregate tables (counts under 11 suppressed) inoutput/or aphi_environment.aggregate_dirsentry. Unset, interactive: ask once with the blocking question tool (else a numbered list) offeringApproved endpoint: full access,Not approved or unsure: schema-only, andNo sensitive data: public or synthetic; save the answer asphi_environment.modethere oncegit check-ignore -q .methodsmith/config.local.yamlpasses (else first add.methodsmith/*.local.yamlto.gitignore) so the guard hook sees it. Unset, headless: schema-only. Inschema-only, write the profiling script, run it only if it prints aggregates, otherwise hand it to the user to run locally, and build the report from that aggregate output. -
When
data_rootis set, in any mode, refresh the identifier index so new extracts are covered: check thatscripts/method-identifier-indexexists in this skill's directory, then run it with the first interpreter found amongpython3, thenpython, thenpy. It prints counts only.SKILL_DIR="<absolute path of the directory containing this SKILL.md>"; python3 "$SKILL_DIR/scripts/method-identifier-index" -
If the dataset is a research cohort built from EHR or claims data, load the
method-cohortskill first — the CONSORT waterfall it produces is the starting point for the row-count check in step 3 below. When__CE_COHORT__appears in chat context oranalysis/cohort/<name>-waterfall.csvexists, use it as the expected-N source instead of re-deriving from the SAP.
Core Workflow
Step 0: Choose QA mode
If a SAP is available, run SAP-aligned QA mode and compare the data to SAP-declared variables, populations, missingness rules, and analysis windows.
If no SAP is available, run pre-SAP column profile mode:
- Inspect the dataset or table schema before
method-planwrites SAP variable/model sections. - Produce row count, column count, column names and types, candidate grain, primary or candidate keys, important date columns, timezone assumptions, null rates, duplicate rates, distinct counts for categorical columns, and basic numeric summaries.
- PHI guard (always, not only in CLIF mode): never echo row-level data, free-text columns, identifiers, or dates of birth into the QA report — report counts and masked samples instead. When listing distinct categorical values with counts in a report that may be shared, suppress categories below the disclosure floor (default n<11 unless the project declares its own floor, for example the CLIF consortium floor of n>=10, or a site or DUA rule is stricter) or bucket them as "other".
- Flag obvious validity issues such as impossible dates, negative counts where not plausible, sentinel missing values, mixed-grain rows, and PHI-suspect columns.
- Do not invent study variables or analysis models. Mark SAP-dependent checks as "deferred until SAP exists."
- Emit
__CE_DATA_PROFILE__somethod-plancan use the actual columns and state which variables remain provisional.
Step 1: Resolve the data wave
Read analysis/data-waves.md; if the project also maintains .methodsmith/data-state.yaml, reconcile it with the same wave id and status. If a specific extract_id was passed, use it; otherwise use the most recently recorded, unlocked wave. Refuse to QA a locked wave unless --force is passed (locked waves are immutable; QA already passed).
Step 2: Parse the SAP for shape expectations
Skip SAP parsing in pre-SAP column profile mode. Instead, treat the observed column profile as planning evidence and label all SAP-dependent thresholds as pending.
Extract from the SAP:
- Population size: expected N from inclusion/exclusion criteria
- Required variables: from SAP-2 (Variables) section
- Variable types: continuous / categorical / time-to-event
- Value sets for categoricals: e.g.,
sex: {M, F},treatment: {placebo, drug} - Date variables: enrollment, randomization, event, censor
- Missingness rule: e.g., "≤ 5% missing per primary outcome variable"
If the SAP doesn't specify these, output a WARN: SAP under-specified finding and proceed with looser defaults.
Step 3: Run the QA checks
CLIF profile: when chat context contains __CE_CLIF__ active=true, additionally run the CLIF-specific gate before the generic checks. Treat https://clif-icu.com/ and the matching version= + mcide_version= values in the CLIF handoff as the authoritative family. If either version is missing, incomplete, or mixed, stop the category check and route to the method-clif skill; do not use a v2.1 cache by default.
- Storage check: refuse to QA non-Parquet inputs for CLIF tables; emit a
blockfinding if asked to QA CSV/Feather data declared as CLIF. - Parquet reader: Parquet needs
pyarrow(orpolars/duckdb) in the Python environment, orarrowin R. If the import fails, stop with the install line for the project's manager (uv add pyarrow, orpip install pyarrowin an activated venv;install.packages('arrow')in R) instead of converting the data to CSV. - ID type check:
patient_idandhospitalization_idare VARCHAR —blockif cast to int. - Datetime check: every
*_dttmcolumn is timezone-aware UTC —blockif any tz-naive timestamps exist. - mCIDE vocabulary check: every
*_categorycolumn conforms to the selected CLIF/mCIDE family. Use the bundled allow-list only for 2.1 + 2.1; for 3.0 + 3.0, read the project’s declared v3 mCIDE source and record it in the report. Each violation is ablock(orwarnwhenstrict=falsewas set on__CE_CLIF__). - Outlier-handling check: physiologic ranges follow
clifpy'soutlier_config.yamlor the project's documented thresholds;warnon out-of-range, never silently clip. - PHI guard: free-text columns (
*_name,clinical_notes_text, rawdischarge_name) are not echoed in the report — replace with a count + sample-of-distinct-after-mask. - Canonical implementation: prefer upstream CLIF tooling when available.
__CE_LANG__ primary=python-> useclifpy'sClifOrchestratorDQA path.__CE_LANG__ primary=r-> use the CLIF project-template QC and outlier-handler pattern. If__CE_LANG__is absent, load themethod-language-detectskill; if stillunknown, surface both implementations. Roll your own only when neither applies.
Causal workflow integrity checks (Python data stacks)
For Python/Pandas/Polars/DuckDB workflows that prepare a causal analysis dataset, run QA-17 through QA-23 in addition to the generic checks. Preserve the risk-based gate: confirmed integrity failures are block; ambiguous methodological or stack-specific risks are warn and require analyst resolution. Never substitute synthetic or fallback data silently. Treat Polars, DuckDB, and large eager-load concerns as warnings unless the run confirms an integrity violation.
Apply each check from references/qa-checks.md against the data. Generate findings into one of these buckets:
| Bucket | Meaning | Effect on gate |
|---|---|---|
block |
Row count, key, type, or value-set violation that makes modeling impossible or unsafe | NO-GO |
warn |
Missingness above expected threshold, distribution shift, suspected outlier cluster | Require PI sign-off |
info |
Cosmetic (column order, label drift) | No effect |
pass |
Check ran cleanly | No effect |
Step 4: Generate the report
When generating the report as an R Markdown or Quarto notebook rather than a static report, load the method-notebook-standards skill before creating or materially extending its executable chunks.
Write to reports/data-qa/<extract_id>.md (markdown) and reports/data-qa/<extract_id>.html (rendered Quarto / RMarkdown) when the project has a Quarto or RMarkdown render path; otherwise the Markdown report is the deliverable and the report states that the .html path was not rendered. Use references/report-template.md. Sections:
- Summary banner (GO / NO-GO / GO with PI sign-off)
- Column profile: row count, column count, names/types, candidate grain, candidate keys, date columns, null rates, duplicate rates
- Wave provenance: extract_id, source, hash, row count, ingestion date
- CONSORT/STROBE flow: enrollment → eligibility → analysis populations, when available
- Missingness map: heatmap (or fallback table), per-variable %
- Findings table: bucket × check × variable × details
- Sign-off block: empty, for PI to fill if
warnbucket non-empty
If any warn finding requires PI approval, add the report path and finding summary to the project signoff ledger used by method-signoff. Data-QA approval must remain separate from the data lock; the ledger records human acceptance of warnings, not permission to mutate locked data.
Step 5: Emit GO/NO-GO and update data state
Always emit a unified handoff signal that method-plan SAP mode reads (and a legacy GO/NO-GO line for backward compatibility):
__CE_DATA_PROFILE__ dataset=<path-or-wave> rows=<n> columns=<n> grain=<candidate-grain-or-unknown> report=<path>
__CE_DATA_QA__ wave=<id> pass=<true|false> blockers=<n> warns=<n> report=<path>
In pre-SAP column profile mode, pass=true means no structural blockers were found in the profile; it does not mean SAP-specific checks have passed. If GO (pass=true): also emit __CE_DATA_QA_PASS__ extract_id=<id> and state that an authorized human may record a dated locked entry only after SAP-aligned QA is complete. If NO-GO (pass=false): also emit __CE_DATA_QA_FAIL__ extract_id=<id> blockers=<count> and stop. Print the path to the report.
Step 6: Compound learning hook
If any block or warn finding fires AND the same finding pattern appeared on a prior extract (lookup via method-learnings-researcher for problem_type: data_quality_issue), suggest method-compound to capture the pattern. Use the heuristic: same variable + same check + ≥ 2 occurrences across studies = compound-worthy.
Pipeline mode
When invoked from an automated workflow (LFG-style, headless method-work, or any disable-model-invocation context), skip the user prompts and emit only the structured signals. The report file is still written.
What This Skill Does NOT Do
- It does not modify the data. This is a read-only assessment. Cleaning is a separate
method-worktask. - It does not lock the data. After SAP-aligned QA, an authorized human records a dated
lockedentry for the wave inanalysis/data-waves.md, naming the QA report path and content hash; update.methodsmith/data-state.yamltoo when the project uses it. - It does not check SAP correctness. That's
method-sap-drift-detector(which now also covers amendments). We check data-vs-SAP shape consistency only. - It does not run statistical models. No fits, no tests, no inferential output. Descriptive only.
References
@./references/qa-checks.md
@./references/report-template.md
@./references/missingness-patterns.md
Files in this skill
5method-data-qa skill questions
How do I install the method-data-qa skill in Claude Code?
Run npx degit sajor2000/methodsmith/plugins/methodsmith/skills/method-data-qa ~/.claude/skills/method-data-qa. Claude Code loads skills from ~/.claude/skills (all projects) or .claude/skills (one project) and uses a skill when its description matches the task.
Which clients can use the method-data-qa skill?
Any client that reads the Agent Skills format: Claude Code, Codex, Gemini CLI and claude.ai (upload as a ZIP). Scripts in the skill run only where the client allows code execution.
What happens if no SAP exists when running this skill?
The skill runs in pre-SAP column profile mode, producing a data profile that can be used by other tools to draft an SAP without inventing variables.
How does the skill handle sensitive PHI data?
The skill follows strict PHI guards, such as suppressing categories with low counts (default n<11) and never echoing row-level data, free-text columns, or identifiers in reports.
What are the possible outcomes of a data quality check?
Outcomes are categorized into block (NO-GO), warn (requires PI sign-off), info (cosmetic), or pass.