automapper-validation 0.49.2

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.
- `verwendungszwecke.json` — chapter 2 of the BDEW Codeliste der Verwendungszwecke (version 1.0 with the corrections of 29.06.2026, valid from FV2610): per code (V01…V33) its locations (MaLo, Tranche, NeLo), the market roles it may be sent to (NB, LF, ÜNB), and what its Erläuterung asks of the OBIS of the same PIA (Messart D, Lieferrichtung via Messgröße C). Loaded by `src/eval/verwendungszwecke.rs`; used by UTILMD Strom FV2610 `[185]`–`[187]`, `[274]`–`[276]`, `[353]`, `[354]`, `[381]`–`[383]`, `[422]`–`[424]`, and by the sample generator for PIA+5 Verwendungszweck codes.
- `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.

**Codeliste der Verwendungszwecke:** list the documents (`GET https://www.bdew-mako.de/api/documents`, titles "Codeliste der Verwendungszwecke …"), download the Word "informatorische Lesefassung" (`GET https://www.bdew-mako.de/api/downloadFile/<fileId>`), then:

```bash
scripts/extract_verwendungszwecke.py crates/automapper-validation/data/verwendungszwecke.json \
    "<version>=<downloaded .docx>" --file-id <fileId>
```

**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.