Data audit (P1)
File: data/firms.csv — SHA-256 34aa682e59ef64cfc56931ea33bb809797cd53eca83edfe370c31aeaa8e8b7df (matches bundle.json; unchanged after analysis).
- 1200 data rows (+ header), 4 columns: firm_id int64 (1001–2200, unique), skill_index float (standardised, mean −0.001, sd 0.99, range −3.83..2.96), training_hours float (hours/employee, mean 19.95, sd 8.24, range −7.585..51.77), productivity_growth float (% change, mean 7.08, sd 4.02, range −4.04..19.39).
- No missing values; no duplicate firm_id; no duplicate rows. No heaping in training_hours (max repeat count 2), no zero hours.
- Anomaly: 12 rows with training_hours < 0 (min −7.585) — physically impossible. All have low skill_index (−3.0..−1.0). Decision: exclude from the main analysis (exclusions.csv step 3); sensitivity keeps them as-is and censored at 0.
- Correlations: hours–skill 0.69, skill–growth −0.79, hours–growth −0.28 → strong confounding by skill expected.
- No dates in file; timing is by definition: skill_index pre-programme (valid control), training_hours during, productivity_growth after. No information-availability violation; no post-treatment variable is used as a control.