v1.8.0 — introspective auto-config controller
Headline
Zero-config auto-config now beats hand-tuned on bibliographic and person-matching benchmarks. No manual blocking key picks, no scorer-weight tuning, no threshold sweeps — just goldenmatch.dedupe_df(df) or goldenmatch.match_df(target, reference) and the controller picks the config.
Benchmarks (zero-config, no manual tuning)
| Dataset | v1.7.1 | v1.8.0 | Hand-tuned ceiling |
|---|---|---|---|
| DBLP-ACM (cross-source match) | 0.5102 | 0.9641 | 0.918 (above ceiling) |
| Febrl3 (single-source dedupe) | 0.8528 | 0.9443 | 0.971 (97% of ceiling) |
| NCVR (corruption GT) | — | 0.9719 | — |
| DQbench ER (no LLM) | 46.24 (hand-tuned) | 62.87 (zero-config) | — |
What's in 1.8
Introspective controller architecture
The controller iterates on a stratified sample, reads stage-emitted complexity signals (block size distribution, score histogram, transitivity rate, candidates compared, mass-borderline), and refines the config via a heuristic refit policy until it converges. Each iteration commits a typed ComplexityProfile to history; the cheapest-healthy entry wins. Stop conditions: green / converged / budget exhausted.
Refit rules (10 total)
rule_blocking_field_null_heavy, rule_blocking_singleton_trap, rule_blocking_key_swap, rule_blocking_too_coarse, rule_uniform_heavy_blocking, rule_unimodal_scoring, rule_low_reduction_ratio, rule_low_transitivity, rule_no_matches, rule_recall_gap_suspected. Each is a pure function (profile, current_config, history) → (new_config, decision) | None.
Cross-run memory
Past committed configs persist in ~/.goldenmatch/autoconfig_memory.db keyed by data-shape signature. Reused on shape match across runs. Opt out: GOLDENMATCH_AUTOCONFIG_MEMORY=0.
LLM policy fallback (optional)
When heuristic rules exhaust without reaching GREEN, an LLMRefitPolicy proposes a config diff. Default off; opt in: GOLDENMATCH_AUTOCONFIG_LLM=1 + OPENAI_API_KEY.
Per-pair LLM scoring auto-enable
When the committed profile shows borderline-heavy scoring AND an LLM API key is available, the controller decorates the committed config with LLMScorerConfig. Adaptive bounds track the matchkey's threshold dynamically — wide mode (auto_threshold=0.99) when mass_in_borderline > 0.5, standard mode otherwise.
Standardization auto-detection
Phone / email / zip / state / first_name / last_name / address columns auto-emit StandardizationConfig rules. The hand-tuned dqbench adapter does this manually; v0 now matches without explicit input.
Quickstart example
New examples/zero_config_quickstart.py — three-example tour of dedupe, cross-source match, and audit-trail inspection.
Public API changes
auto_configure_df(df, *, reference=None, ...)— gains optionalreferencekwarg for cross-source match mode. Otherwise unchanged.PostflightReport— newcontroller_profileandcontroller_historyfields surface the typedComplexityProfileand audit trail.- New env vars (default off):
GOLDENMATCH_AUTOCONFIG_MEMORY,GOLDENMATCH_AUTOCONFIG_LLM.
Breaking changes
None. All public API additions are backward compatible.
Followups
The DQbench gap to the published 95.30 ceiling is gated on:
- Letting the controller commit YELLOW configs when no GREEN candidate exists (currently
cheapest_healthy()filters too aggressively). - Stronger T1/T2-class rules — uniform-heavy blocking detection ships in 1.8 but doesn't cover every pathology DQbench's synthetic data exposes.
Both are tracked for the next iteration.
Install
```bash
pip install --upgrade goldenmatch
```
PyPI release auto-published via trusted-publishing on this tag.
Full session
14 PRs (#102–#115) in the goldenmatch repo: see CHANGELOG.md for the per-PR mapping.