Pipeline Audit — Adversarial Data Review
v1.0 — Adversarial reviewer that challenges data pipeline outputs, assumptions, and integrity. Complements /code-review (which reviews code quality) by testing what the code actually produced.
Review the outputs of a data cleaning or analysis pipeline by reading the data, checking for anomalies, and challenging the assumptions embedded in the pipeline. This is the "red team" for your data work.
Argument: $ARGUMENTS
- Path to a directory containing .dta output files (e.g.,
data/for_analysis/)
- Or a project name (will look in
~/Dropbox/Github/[project]/)
- Or a specific .dta file to audit
Modes (append to argument):
quick (default) — Scan outputs for red flags: duplicate IDs, unexpected missingness, implausible values
deep — Full adversarial review: all quick checks + cross-file consistency, merge integrity, distribution analysis
pre-submission — Publication-readiness check: all deep checks + AEA-style output verification, table-to-code tracing
Flags:
scope:cleaning — Focus on cleaning pipeline outputs (raw -> for_analysis)
scope:analysis — Focus on analysis outputs (regressions, tables)
vars:consumption,assets — Focus on specific variable families
baseline:path/to/old.dta — Compare against a previous version
Example: /pipeline-audit ~/Dropbox/Github/graduation-coaching/data/for_analysis/ deep
Example: /pipeline-audit data/for_analysis/endline_analysis.dta quick vars:consumption
Example: /pipeline-audit bd-social scope:cleaning
Instructions
Step 0: Locate Data and Context
- Resolve
$ARGUMENTS to find the target .dta file(s):
- If a directory: glob for
*.dta files, report count
- If a project name: check
~/Dropbox/Github/[project]/data/for_analysis/, data/, output/
- If a single file: use directly
- Read the project's
AGENTS.md, CLAUDE.md, or README.md if available — look for:
- Expected unique identifiers (hhid, id, respondent_id)
- Expected sample sizes
- Variable naming conventions
- Known data quality issues
- If a
docs/ or codebook/ directory exists, scan for data documentation
Parse mode and flags from $ARGUMENTS. Default to quick.
Step 1: Structural Integrity
Write a temporary Python script for all checks (use uv run python or python3). Never use python -c.
For each .dta file:
1.1 ID Integrity
- Detect likely ID columns (hhid, id, respondent_id, or columns ending in
_id)
- Test uniqueness:
df[id_col].is_unique
- Report any duplicates with sample rows
- If multiple .dta files share an ID column, verify consistent ID sets across files
1.2 Shape and Completeness
- Report: rows, columns, memory usage
- Flag files with 0 rows (empty output = pipeline failure)
- Flag files where >50% of columns are entirely missing
- Flag any column that is 100% missing
1.3 Variable Type Audit
- Count: numeric, string, categorical columns
- Flag columns where the name suggests numeric but the type is string (e.g.,
income_total as string)
- Flag columns where >90% of values are the same (constant or near-constant)
Step 2: Value Plausibility (all modes)
2.1 Distributional Red Flags
For each numeric column:
- Flag if min < 0 for variables that should be non-negative (expenditure, count, age, income)
- Flag extreme outliers: values > 10x the 99th percentile or < -10x the 1st percentile
- Flag suspiciously round distributions (all values multiples of 100, 1000, etc.)
- Report top 5 columns by coefficient of variation (most dispersed)
2.2 Missing Value Patterns
- Report overall missingness rate per column
- Flag columns where missingness is suspiciously correlated with treatment/control (if treatment variable detected)
- Flag columns where missingness jumps sharply compared to nearby columns in the dataset
- Check for sentinel codes that survived cleaning (-99, -88, -77, -66 in numeric columns)
2.3 Categorical/Indicator Checks
- For binary (0/1) columns: report balance. Flag if <1% or >99% are 1 (degenerate)
- For categorical columns: report number of unique values. Flag if >100 unique values (may be continuous stored as categorical)
- Check value labels exist for categorical variables (via pyreadstat metadata)
Step 3: Cross-File Consistency (deep and pre-submission modes)
Skip for quick mode.
3.1 ID Coverage
- If multiple .dta files share an ID column:
- Are the ID sets identical? Report any IDs present in one file but not another
- Do key structural variables (treatment arm, strata, demographics) match across files?
3.2 Variable Consistency
- If the same variable name appears in multiple files:
- Do the distributions match? (Compare means, SDs, ranges)
- Flag any where the mean differs by >10%
3.3 Merge Residue
- Flag any
_merge variables that survived into the output (should be dropped)
- Flag any variables named
_* that look like temporary leftovers
Step 4: Assumption Challenges (deep and pre-submission modes)
Skip for quick mode.
This is the adversarial core. Challenge the pipeline's implicit assumptions:
4.1 Sample Selection Bias
- If treatment variable exists: compare sample sizes by arm. Flag imbalance >10%
- Check if missingness patterns differ by treatment arm for key outcomes
- If attrition variable exists: profile attriters vs non-attriters on baseline characteristics
4.2 Construction Validity
- For index/composite variables: check correlation with components. Flag if a component has near-zero correlation with the composite (may not belong)
- For per-capita variables: verify denominator is reasonable (household size > 0, not missing)
- For currency-converted variables: verify conversion factor is plausible (not 0, not extreme)
4.3 Winsorization / Trimming
- Detect winsorized variables (names containing
wins, _w, _tr)
- Verify winsorization was applied (compare min/max to percentile boundaries)
- Flag if winsorization thresholds seem too aggressive (>5% each tail)
4.4 Time / Date Variables
- Check date variables for future dates (data entry errors)
- Check for dates outside the study period
- Flag if interview date range is implausibly short or long
Step 5: Analysis Output Checks (pre-submission mode only)
Skip for quick and deep modes.
5.1 Regression Output Tables
- If results .dta or .csv files exist, check:
- Do coefficient signs match economic intuition? (Treatment effects positive for graduation programs)
- Are standard errors plausible relative to coefficient size?
- Are sample sizes consistent across specifications?
- Do R-squared values seem reasonable for the model type?
5.2 Table-to-Data Traceability
- For each regression output: can we identify which .dta was the input?
- Are all outcome variables in the output traceable to a column in the analysis dataset?
Step 6: Generate Report
Save report to:
- Same directory as reviewed data:
pipeline_audit_[YYYY-MM-DD].md
- Or project root if reviewing a project
Classify each finding:
- RED FLAG — Data integrity violation. Likely pipeline bug or data corruption. Investigate immediately.
- ORANGE FLAG — Suspicious pattern that may indicate a problem. Verify before proceeding.
- YELLOW FLAG — Unusual but potentially intentional. Document the decision if keeping.
- CLEAN — Passed the check.
Output Format
# Pipeline Audit: [project/directory]
**Date:** [YYYY-MM-DD]
**Mode:** [quick / deep / pre-submission]
**Files reviewed:** [N] .dta files ([total rows] observations, [total cols] variables)
**Reviewer:** /pipeline-audit v1.0
---
## Executive Summary
**Overall assessment:** [Clean / Minor Issues / Investigate / Significant Problems]
[2-3 sentences: what was checked, what was found, what needs attention]
**Red flags:** [N] | **Orange flags:** [N] | **Yellow flags:** [N] | **Clean checks:** [N]
---
## Red Flags
### RF1: [Title]
- **File:** [filename]
- **Issue:** [description]
- **Evidence:** [specific values, counts, or statistics]
- **Action:** [what to investigate or fix]
---
## Orange Flags
### OF1: [Title]
- **File:** [filename]
- **Issue:** [description]
- **Evidence:** [evidence]
- **Question:** [what to verify — phrased as a question for the PI]
---
## Yellow Flags
[Brief list format]
- **YF1:** [file] — [issue] — [why it might be OK]
---
## Clean Checks
| Check | Status | Notes |
|-------|--------|-------|
| ID uniqueness | PASS | [N] files, all unique on [hhid] |
| No empty files | PASS | All [N] files have data |
| No sentinel codes | PASS | No -99/-88/-77 in numeric columns |
| ... | ... | ... |
---
## File Inventory
| File | Rows | Cols | ID Column | Missing Rate | Notes |
|------|------|------|-----------|-------------|-------|
| [name] | [N] | [N] | [col] | [%] | [any flags] |
---
## Next Steps
1. [Highest-priority investigation]
2. [Second priority]
3. [Third priority]
Principles
- Adversarial, not adversary. The goal is to find problems before reviewers, referees, or replicators do. Every flag is an opportunity to strengthen the work.
- Evidence-based. Every finding includes specific numbers, rows, or statistics. "Something looks wrong" is not a finding.
- Calibrated severity. A duplicate ID is a red flag. An unusual distribution is a yellow flag. Don't cry wolf.
- Ask, don't assume. When a pattern is ambiguous, phrase the finding as a question for the PI: "Is it expected that 23% of treated households have missing consumption data?"
- Respect the pipeline. The cleaning code may have already handled an issue. Check the code/logs before flagging something the pipeline explicitly addresses.
- No false comfort. A clean audit doesn't mean the data is perfect — it means the checks you ran didn't find problems. State what you checked and what you didn't.
1---2name: pipeline-audit3description: Adversarial data pipeline review — audits variable construction, sample restrictions, and analytical decisions against pre-analysis plans4---56# Pipeline Audit — Adversarial Data Review78*v1.0 — Adversarial reviewer that challenges data pipeline outputs, assumptions, and integrity. Complements /code-review (which reviews code quality) by testing what the code actually produced.*910Review the outputs of a data cleaning or analysis pipeline by reading the data, checking for anomalies, and challenging the assumptions embedded in the pipeline. This is the "red team" for your data work.1112**Argument:** `$ARGUMENTS`13- Path to a directory containing .dta output files (e.g., `data/for_analysis/`)14- Or a project name (will look in `~/Dropbox/Github/[project]/`)15- Or a specific .dta file to audit1617**Modes** (append to argument):18- `quick` (default) — Scan outputs for red flags: duplicate IDs, unexpected missingness, implausible values19- `deep` — Full adversarial review: all quick checks + cross-file consistency, merge integrity, distribution analysis20- `pre-submission` — Publication-readiness check: all deep checks + AEA-style output verification, table-to-code tracing2122**Flags:**23- `scope:cleaning` — Focus on cleaning pipeline outputs (raw -> for_analysis)24- `scope:analysis` — Focus on analysis outputs (regressions, tables)25- `vars:consumption,assets` — Focus on specific variable families26- `baseline:path/to/old.dta` — Compare against a previous version2728Example: `/pipeline-audit ~/Dropbox/Github/graduation-coaching/data/for_analysis/ deep`29Example: `/pipeline-audit data/for_analysis/endline_analysis.dta quick vars:consumption`30Example: `/pipeline-audit bd-social scope:cleaning`3132---3334## Instructions3536### Step 0: Locate Data and Context37381. Resolve `$ARGUMENTS` to find the target .dta file(s):39 - If a directory: glob for `*.dta` files, report count40 - If a project name: check `~/Dropbox/Github/[project]/data/for_analysis/`, `data/`, `output/`41 - If a single file: use directly422. Read the project's `AGENTS.md`, `CLAUDE.md`, or `README.md` if available — look for:43 - Expected unique identifiers (hhid, id, respondent_id)44 - Expected sample sizes45 - Variable naming conventions46 - Known data quality issues473. If a `docs/` or `codebook/` directory exists, scan for data documentation4849Parse mode and flags from `$ARGUMENTS`. Default to `quick`.5051---5253### Step 1: Structural Integrity5455Write a temporary Python script for all checks (use `uv run python` or `python3`). Never use `python -c`.5657For each .dta file:5859#### 1.1 ID Integrity60- Detect likely ID columns (hhid, id, respondent_id, or columns ending in `_id`)61- Test uniqueness: `df[id_col].is_unique`62- Report any duplicates with sample rows63- If multiple .dta files share an ID column, verify consistent ID sets across files6465#### 1.2 Shape and Completeness66- Report: rows, columns, memory usage67- Flag files with 0 rows (empty output = pipeline failure)68- Flag files where >50% of columns are entirely missing69- Flag any column that is 100% missing7071#### 1.3 Variable Type Audit72- Count: numeric, string, categorical columns73- Flag columns where the name suggests numeric but the type is string (e.g., `income_total` as string)74- Flag columns where >90% of values are the same (constant or near-constant)7576---7778### Step 2: Value Plausibility (all modes)7980#### 2.1 Distributional Red Flags81For each numeric column:82- Flag if min < 0 for variables that should be non-negative (expenditure, count, age, income)83- Flag extreme outliers: values > 10x the 99th percentile or < -10x the 1st percentile84- Flag suspiciously round distributions (all values multiples of 100, 1000, etc.)85- Report top 5 columns by coefficient of variation (most dispersed)8687#### 2.2 Missing Value Patterns88- Report overall missingness rate per column89- Flag columns where missingness is suspiciously correlated with treatment/control (if treatment variable detected)90- Flag columns where missingness jumps sharply compared to nearby columns in the dataset91- Check for sentinel codes that survived cleaning (-99, -88, -77, -66 in numeric columns)9293#### 2.3 Categorical/Indicator Checks94- For binary (0/1) columns: report balance. Flag if <1% or >99% are 1 (degenerate)95- For categorical columns: report number of unique values. Flag if >100 unique values (may be continuous stored as categorical)96- Check value labels exist for categorical variables (via pyreadstat metadata)9798---99100### Step 3: Cross-File Consistency (deep and pre-submission modes)101102*Skip for `quick` mode.*103104#### 3.1 ID Coverage105- If multiple .dta files share an ID column:106 - Are the ID sets identical? Report any IDs present in one file but not another107 - Do key structural variables (treatment arm, strata, demographics) match across files?108109#### 3.2 Variable Consistency110- If the same variable name appears in multiple files:111 - Do the distributions match? (Compare means, SDs, ranges)112 - Flag any where the mean differs by >10%113114#### 3.3 Merge Residue115- Flag any `_merge` variables that survived into the output (should be dropped)116- Flag any variables named `_*` that look like temporary leftovers117118---119120### Step 4: Assumption Challenges (deep and pre-submission modes)121122*Skip for `quick` mode.*123124This is the adversarial core. Challenge the pipeline's implicit assumptions:125126#### 4.1 Sample Selection Bias127- If treatment variable exists: compare sample sizes by arm. Flag imbalance >10%128- Check if missingness patterns differ by treatment arm for key outcomes129- If attrition variable exists: profile attriters vs non-attriters on baseline characteristics130131#### 4.2 Construction Validity132- For index/composite variables: check correlation with components. Flag if a component has near-zero correlation with the composite (may not belong)133- For per-capita variables: verify denominator is reasonable (household size > 0, not missing)134- For currency-converted variables: verify conversion factor is plausible (not 0, not extreme)135136#### 4.3 Winsorization / Trimming137- Detect winsorized variables (names containing `wins`, `_w`, `_tr`)138- Verify winsorization was applied (compare min/max to percentile boundaries)139- Flag if winsorization thresholds seem too aggressive (>5% each tail)140141#### 4.4 Time / Date Variables142- Check date variables for future dates (data entry errors)143- Check for dates outside the study period144- Flag if interview date range is implausibly short or long145146---147148### Step 5: Analysis Output Checks (pre-submission mode only)149150*Skip for `quick` and `deep` modes.*151152#### 5.1 Regression Output Tables153- If results .dta or .csv files exist, check:154 - Do coefficient signs match economic intuition? (Treatment effects positive for graduation programs)155 - Are standard errors plausible relative to coefficient size?156 - Are sample sizes consistent across specifications?157 - Do R-squared values seem reasonable for the model type?158159#### 5.2 Table-to-Data Traceability160- For each regression output: can we identify which .dta was the input?161- Are all outcome variables in the output traceable to a column in the analysis dataset?162163---164165### Step 6: Generate Report166167**Save report to:**168- Same directory as reviewed data: `pipeline_audit_[YYYY-MM-DD].md`169- Or project root if reviewing a project170171**Classify each finding:**172- **RED FLAG** — Data integrity violation. Likely pipeline bug or data corruption. Investigate immediately.173- **ORANGE FLAG** — Suspicious pattern that may indicate a problem. Verify before proceeding.174- **YELLOW FLAG** — Unusual but potentially intentional. Document the decision if keeping.175- **CLEAN** — Passed the check.176177---178179## Output Format180181```markdown182# Pipeline Audit: [project/directory]183184**Date:** [YYYY-MM-DD]185**Mode:** [quick / deep / pre-submission]186**Files reviewed:** [N] .dta files ([total rows] observations, [total cols] variables)187**Reviewer:** /pipeline-audit v1.0188189---190191## Executive Summary192193**Overall assessment:** [Clean / Minor Issues / Investigate / Significant Problems]194195[2-3 sentences: what was checked, what was found, what needs attention]196197**Red flags:** [N] | **Orange flags:** [N] | **Yellow flags:** [N] | **Clean checks:** [N]198199---200201## Red Flags202203### RF1: [Title]204- **File:** [filename]205- **Issue:** [description]206- **Evidence:** [specific values, counts, or statistics]207- **Action:** [what to investigate or fix]208209---210211## Orange Flags212213### OF1: [Title]214- **File:** [filename]215- **Issue:** [description]216- **Evidence:** [evidence]217- **Question:** [what to verify — phrased as a question for the PI]218219---220221## Yellow Flags222223[Brief list format]224- **YF1:** [file] — [issue] — [why it might be OK]225226---227228## Clean Checks229230| Check | Status | Notes |231|-------|--------|-------|232| ID uniqueness | PASS | [N] files, all unique on [hhid] |233| No empty files | PASS | All [N] files have data |234| No sentinel codes | PASS | No -99/-88/-77 in numeric columns |235| ... | ... | ... |236237---238239## File Inventory240241| File | Rows | Cols | ID Column | Missing Rate | Notes |242|------|------|------|-----------|-------------|-------|243| [name] | [N] | [N] | [col] | [%] | [any flags] |244245---246247## Next Steps2482491. [Highest-priority investigation]2502. [Second priority]2513. [Third priority]252```253254---255256## Principles257258- **Adversarial, not adversary.** The goal is to find problems before reviewers, referees, or replicators do. Every flag is an opportunity to strengthen the work.259- **Evidence-based.** Every finding includes specific numbers, rows, or statistics. "Something looks wrong" is not a finding.260- **Calibrated severity.** A duplicate ID is a red flag. An unusual distribution is a yellow flag. Don't cry wolf.261- **Ask, don't assume.** When a pattern is ambiguous, phrase the finding as a question for the PI: "Is it expected that 23% of treated households have missing consumption data?"262- **Respect the pipeline.** The cleaning code may have already handled an issue. Check the code/logs before flagging something the pipeline explicitly addresses.263- **No false comfort.** A clean audit doesn't mean the data is perfect — it means the checks you ran didn't find problems. State what you checked and what you didn't.