Data audit (P1)
File: data/firms.csv — SHA-256 34aa682e59ef64cfc56931ea33bb809797cd53eca83edfe370c31aeaa8e8b7df
- 1200 rows (header excluded), 4 columns: firm_id (int, 1001–2200, unique), skill_index (float, standardised, mean -0.001, range -3.83..2.96), training_hours (float, hours/employee, mean 19.9, range -7.585..51.77), productivity_growth (float, %, mean 7.08, range -4.04..19.39).
- Missing values: none. Duplicate rows: none. Duplicate firm_id: none. No dates (single cross-section; skill pre-programme, hours during, growth after — timing respects pre-treatment conditioning).
- No |z|>4 outliers in any column; no heaping in training_hours (max multiplicity 2).
- Anomaly: 12 rows with training_hours < 0 (all low-skill firms, skill -3.0..-0.99), physically impossible. Handling: retained in main model (consistent with continuous simulated DGP tail; dropping truncates on treatment), sensitivity excluding them (n=1188) reported.
- Correlations: corr(skill, hours)=0.69, corr(skill, growth)=-0.79, corr(hours, growth)=-0.28 → strong confounding by skill expected.
- Info-availability: skill_index measured before the programme → valid pre-treatment control. No input violates the rules.