automapper-validation 0.12.0

AHB condition expression parsing, evaluation, and EDIFACT validation
Documentation
# BDEW Codelist & EBD Cluster Data

Machine-readable lookup tables used by the condition evaluator. Two upstream sources:

- BDEW [Codeliste der Artikelnummern und Artikel-ID v5.6 (Fehlerkorrektur 2025-09-30)](https://bdew-mako.de/pdf/Codeliste_Artikelnummern%20und%20Artikel-ID_5_6_Fehlerkorrektur_20250930.pdf) (via BNetzA *"Änderungsmanagement"*) for the Artikel-ID tables.
- Hochfrequenz [mako_prozesse](https://github.com/Hochfrequenz/mako_prozesse) for the per-EBD answer-code cluster map (parsed from BDEW EBD PDFs).

## Files

- `artikel_id_codelist.json` — chapter 3 (Gruppenartikel-ID / Artikel-ID). Loaded at runtime via `ArtikelIdCodelist::embedded()` in `crates/automapper-validation/src/eval/codelist.rs`. Used by conditions `[73]` and `[284]`.
- `artikelnummer_codelist.json` — chapter 2 (5-digit Artikelnummern, INVOIC/residual MMM usage). **Not yet wired into the evaluator**; committed in anticipation of future conditions that reference chapter-2 codes (MMM workflows). Loader is not yet implemented.
- `ebd_cluster_map.json` — per-EBD (`E_0624`, `E_0047`, ...) map `{ code → cluster }` where cluster ∈ {`Zustimmung`, `Ablehnung`, `Ablehnung auf Kopfebene`, `Ablehnung auf Positionsebene`, `Ablehnung auf Summenebene`, `Korrekturliste wegen Ablehnung`, `Änderung der Daten`, `Abweisung`, ...}. Loaded via `EbdClusterLookup::embedded()` in `src/eval/ebd_cluster.rs`. Used by conditions `[359]` / `[360]` / `[366]` / `[368]` (UTILMD_Strom), `[17]` / `[18]` (ORDRSP), `[61]` (UTILTS), and `[14]` / `[15]` / `[16]` / `[517]` / `[518]` (REMADV). Each caller reads the answer code and EBD id from its segment-specific layout (STS/C556 or AJT) and classifies via the lookup. Extracted by `scripts/extract_ebd_clusters.py`, which reads the dedicated `if_yes_cluster` / `if_no_cluster` keys (preferred, introduced upstream after [mako_prozesse#5](https://github.com/Hochfrequenz/mako_prozesse/issues/5)) and falls back to the legacy `Cluster:` prefix in `if_*_hint`.

## Updating

**Artikel-ID codelist:** when BDEW publishes a new PDF, re-extract both JSON files manually (the Rust extraction CLI is deferred — see `docs/plans/2026-04-23-ahb-codelist-and-per-instance-plan.md` Task A8). Spot-check against known entries before committing; bump `version` and `source_published` in both file headers.

**EBD cluster map:** `git pull` the mako_prozesse repo, then:

```bash
scripts/extract_ebd_clusters.py /path/to/mako_prozesse \
    crates/automapper-validation/data/ebd_cluster_map.json \
    --commit "$(git -C /path/to/mako_prozesse rev-parse HEAD)"
```

Spot-check `ebds["E_0624"]` (and any EBDs referenced by newly-added STS conditions) against the upstream YAML before committing.