diff --git a/docs/superpowers/plans/2026-05-18-alpha-id-icd-suggestion.md b/docs/superpowers/plans/2026-05-18-alpha-id-icd-suggestion.md index 1436304..0d59688 100644 --- a/docs/superpowers/plans/2026-05-18-alpha-id-icd-suggestion.md +++ b/docs/superpowers/plans/2026-05-18-alpha-id-icd-suggestion.md @@ -1084,8 +1084,81 @@ git commit -m "feat: RRF and cross-segment max-score dedupe" --- +### Task 9b: ClaML Modifier/ModifierClass expansion (Revision 2026-05-18, spec §3a) + +**Why:** ~26.5% of valid Alpha-ID primary codes are 6-char 5th-digit codes (e.g. `E11.72`, `I10.91`). ClaML models the 4th/5th digit of many groups (incl. all E10–E14 diabetes) only via ``/``, not as ``. Task 4's `claml::load` returns no entry for these, so billability/description are wrong (fall back to the 3-digit `Para295=V` root) — `--billable-only` silently drops ~1,193 distinct billable codes, breaking Goal 1. Decided resolution: expand modifiers correctly from the ClaML file alone. + +**Files:** +- Modify: `src/claml.rs` (extend `load` to also expand subclassification) +- Test: `tests/claml_modifier_tests.rs` + +- [ ] **Step 1: Failing test** — `tests/claml_modifier_tests.rs` + +```rust +use alpha_id::claml; + +#[test] +fn expands_diabetes_5th_digit_codes_as_billable() { + let map = claml::load("icd-claml/Klassifikationsdateien/icd10gm2026syst_claml_20250912.xml").unwrap(); + // E11.x 5th-digit codes are NOT explicit ; must be synthesized. + let e1190 = map.get("E11.90").expect("E11.90 synthesized from ModifierClass"); + assert_eq!(e1190.para295, "P", "terminal 5th-digit diabetes code must be billable"); + assert!(e1190.description.to_lowercase().contains("diabetes"), + "composed description from parent + modifier labels: {:?}", e1190.description); + let e1172 = map.get("E11.72").expect("E11.72 synthesized"); + assert_eq!(e1172.para295, "P"); + // Explicit entries still win and are unchanged. + let a010 = map.get("A01.0").expect("A01.0 explicit"); + assert_eq!(a010.para295, "P"); + assert!(a010.description.contains("Typhus abdominalis")); + // The bare 3-digit root stays non-billable (V). + assert_eq!(map.get("E11").expect("E11 root").para295, "V"); +} +``` + +- [ ] **Step 2: Run** `cargo test --test claml_modifier_tests` → FAIL (`E11.90` absent). + +- [ ] **Step 3: Implement the ClaML subclassification expansion in `src/claml.rs`.** + +This is the standard ClaML modifier algorithm. There is no verbatim code block here because the exact element/attribute handling must be derived against the real XML; the implementer (capable model) must: + - During the stream parse, additionally collect: for each ``, its ordered `` references; the full set of `` (each with its `` children) and `` (each with its preferred `