Verification checks (P4)
- Clean re-run (deleted results.json, analytic.csv, exclusions.csv; re-ran analysis.py): results.json byte-identical (
cmp). PASS - analytic.csv rows (1800) == n_analysed; distinct firms (300) == n_firms; columns = firm_id, year, leverage, cash_ratio, log_sales, default_next (no rating_2025). PASS
- Exclusion ledger: n_before - n_removed = n_after on every row; chained; starts at 2140 = n_input_rows; ends at 1800 = n_analysed. 2140 - 40 - 300 = 1800. PASS
- default_rate equals mean of default_next in analytic.csv. PASS
- Information timing: max origin year in sample 2021 (outcome 2022 <= data cut); no predictor known after end of t. PASS
- No duplicate firm-year keys in analytic sample. PASS
- Independent numpy re-computation of OLS beta, CR1 cluster SE and R2 matches statsmodels (0.26378, 0.04076, 0.03491). PASS
- SE > 0; 95% CI [0.184, 0.344] contains estimate. PASS
- Magnitude vs baseline: default_rate 0.121; beta 0.264 per unit leverage => moving leverage 0.2->0.6 changes predicted PD by ~0.105, plausible relative to baseline. PASS