The expected-maximum-profit (EMP) measurement layer: the loop now reports what being wrong on the declined population costs, not only whether it is miscalibrated.
Calibration says whether the model is wrong on the declines; v0.2.0 adds the axis that says what it costs — two EMP variants computed from the same in-process scores, strictly as reporting. ECE remains the sole loop-control metric, and every v1 column of the committed frontier CSVs is byte-identical.
The frontier is a distribution, not a point. Across the full 25-seed set, the published single-seed frontier (0.4, seed 42) sits at the optimistic end: in the SCM world the median frontier is 0.2, with only 11/25 seeds reaching 0.4 (flat world: median 0.4, 15/25). The boundary is honestly 0.2–0.4 depending on the draw — the prior headline was a valid instance, not a center.
The two EMP variants disagree — and the disagreement is the finding. The literature's convenience prior assumes ROI = 0.2644 where this 60-day daily-ACH loan structure actually returns 0.0875 — a 3.0× overstatement — and places 55% of defaults at full recovery where the harness plants ~1%. Priced honestly, profit on the declined pool collapses toward zero as severity rises; priced by the standard prior, it appears to grow. Same model, same scores, opposite conclusion.
| world | min | median | max | seeds at 0.4 | seeds at 0.2 |
|---|---|---|---|---|---|
| flat | 0.2 | 0.4 | 0.4 | 15/25 | 10/25 |
| SCM | 0.2 | 0.2 | 0.4 | 11/25 | 14/25 |
| selection severity | 0.0 | 0.2 | 0.4 | 0.6 |
|---|---|---|---|---|
| literature empc (naive) | 0.0217 | 0.0331 | 0.0416 | 0.0420 ↑ |
| harness emp_h (naive) | 0.0387 | 0.0297 | 0.0139 | 0.0024 ↓ |
Added 6 entries›
cldd.emp— two EMP variants over the same in-process scores, pure numpy, zero RNG:empc_literature(Verbraken et al. 2014 closed form over the ROC convex hull, with the source-verified prior) andemp_harness(this harness's own loan economics + planted per-row default timing; SCM cohorts only). Both are ranking-only: invariant to any strictly monotone transform of the score.- EMP columns on
SubgroupMetrics/LeverMetricsand in the frontier CSVs, plus an EMP-vs-severity panel on the frontier plot. RoundResult.exploration_cost— the exploration lever's bought labels priced in dollars (new column inartifacts/exploration_frontier.csv).f1_emp_cutoff— F1 at the EMP-optimal cutoff, reported alongside F1 at the arbitrary 0.5 policy threshold (retained for continuity, now documented as diagnostic-only).scripts/run_frontier_sweep.py— the frontier's distribution across the 25-seed set, replacing a single-seed point estimate; one subprocess per run, resumable.- 26 new tests (149 total): hand-computed convex-hull cases, monotone-invariance, degenerate-timing cases, cross-process float determinism.
Changed 3 entries›
- EMP is a reporting axis only — ECE remains the sole loop-control metric. Loop decisions, the frontier, and every v1 column of the committed frontier CSVs are unchanged (byte-identity verified; EMP columns strictly appended).
- Renamed the loop driver and artifacts to drop pre-release lineage naming:
run_clue.py→run_loop.py,clue_frontier*→loop_frontier*(history-preserving renames; CSV contents byte-identical). - Moved the accompanying article
FABLE.md→docs/assessment.md(history-preserving; a dated provenance snapshot, excluded from the Sphinx build).
Fixed 1 entry›
ExplorationCorrectorraisedZeroDivisionErrorwhen constructed withexploration_rate = 0.0(the inverse-propensity weight was evaluated eagerly even though no row can be explored). Unreachable throughSelectiveLabelsLoop, so no committed number changes.
Reading caveats 4 boundaries, stated›
- Raw EMP moves with world hardness. A riskier declined pool changes EMP even for a perfect model — read the two variants against each other at fixed severity, not the trend in isolation.
emp_hrests on unfitted timing.days_to_defaultis planted but never validated against real recovery data — a verified experiment, not a verified result.- Post-term defaults are imputed — ~22.5% of planted defaults land past the 60-day term and are priced at the cohort's mean in-term loss fraction (a stated convention, not measured truth).
emp_his SCM-only — the flat generator plants no timing, so itsemp_hcolumns are empty by design.