---
name: avtero_subpart_unit_gate
description: avtero v0.7.29 — «запчасть узла ≠ узел»: excludes+25 суб-категорий, _cat на канонических строках, фикс dict-vehicle в гейте (офлайн-цепочка была мертва), WMI 1486
metadata:
  node_type: memory
  type: project
  originSessionId: 4eea915e-3b47-4cd5-8a0e-bfa29b78a87c
---

**v0.7.29 (2026-07-03, D-subpart-never-unit + D-wmi-carlike-addonly).** Слои категорий 259→**284/284/289**: +25 суб-детальных (бендикс/втягивающее/щётки стартера, щётки/регулятор/диодный мост/шкив генератора, ремкомплект рейки, гидроблок/ГДТ/соленоид АКПП, сетка бензонасоса, мотор стеклоподъёмника, лампа, блок розжига, крестовина рулевого вала, радиатор EGR, корпус термостата, наконечник катушки, венец маховика, ремень вариатора, комплект ГРМ, распылитель форсунки…) + excludes на 16+ узловых правил. Батарея `tests/test_unit_subpart_split.py` (88).

**КРИТИЧЕСКИЙ пойманный баг:** `_enforce_named_parts` передаёт vehicle СЛОВАРЁМ, `_resolve_named_part` читал поля getattr → None → офлайн-цепочка гейта (live_harvest/деревья/TecDoc-фолбэк) была МЕРТВА с v0.7.21, маскировалась live-путями RU-каталожных машин; вскрылось на US-Kia (все blank), после чего loose-филлеры (`_apply_domestic_tecdoc_oe` fill, fitment-бэкфилл) добивали blank-и категорией УЗЛА (emex loose-словарь не знает суб-категорий): «шкив»=«щётки»=«генератор»=37321-25201. Фикс (`orchestrator.py.bak-gatevehicle-*`): dict→SimpleNamespace на входе резолвера; канонические строки несут `_cat`; все loose-филлеры берут `_cat` в приоритет; tecdoc-fill скипает `_named_blank`. Регресс `tests/test_named_gate_vehicle_dict.py`. **Урок: тестов мало — только живой прогон на НЕ-RU-каталожной машине (US VIN) вскрывает мёртвые ветки.**

**WMI:** `scripts/build_wmi_combined.py` (идемпотентный) — wmi_combined.json 1163→**1486** (+325 легковых 3-симв. из vpic: Rivian/Lucid/Fisker/Polestar/Ineos/Genesis…; трейлеры/мото/6-симв./юрлица НЕ вливать — отравят гардрейл; 112/1TK удалены, 3N6→Nissan; 132 спорных в `/Volumes/Ext/avtero/vin_ref/wmi_merge_report-20260703.json`). Полного бесплатного реестра WMI не существует (SAE платный). lru_cache → нужен рестарт после правки JSON.

**v0.7.31 (2026-07-03) — класс-excludes в деревьях (`local_brands.py.bak-catvehex-*`):** harness вскрыл Kia «масляный фильтр»→46321-26000 S1 (это ФИЛЬТР АКПП — febi филит ATF под «Transmission Oil Filter», широкий паттерн `oil filter` ловил). `_CAT_VEH_EX` = негативные подстроки на класс, в SQL всех 4 матчеров через `_ex_where(cat,field)`: oil_filter≠transmission/акпп/коробк/вариатор/cvt; shock_absorber≠gas spring/багажник/капот. `_pick_make_oe` срезает хвост ` S\d`. Kia→26320-27400 (genuine oil filter). Регресс `tests/test_catveh_class_excludes.py` (4), suite 1002. Vesta→RENAULT-фильтр = ОСОЗНАННАЯ концерн-группа `_MAKE_CONCERN {renault,dacia,lada}` (tecdoc_local:163)+фитмент по K-type, НЕ дыра. ~~Открытый предел~~ ЗАКРЫТ в v0.7.32 (см. ниже).

**v0.7.32 (2026-07-03) — engine-honesty note (D-engine-honesty):** мотор-зависимые категории `_ENGINE_CATS` (oil/fuel filter, spark/glow plug, ignition_coil, injector, timing_belt/chain/kit, drive_belt, water_pump, thermostat, pcv_valve) при НЕИЗВЕСТНОМ двигателе → `_mark_engine` ставит `confident=False`+оговорку «уточните двигатель/сверьте по артикулу». Зеркало `_mark_axle`; флажит ТОЛЬКО engine-blind фолбэки (`_vehicle_oe_no_vin` деревья + tecdoc make-level). VIN-native/frame/live-harvest НЕ трогает (мотор закодирован); двигатель известен → tecdoc сужает K-типы→engine-exact→флага нет. Регресс `tests/test_engine_honesty.py` (4), suite 1047. Живьём: Kia (движок не декодился)→26320-27400+оговорка; Volvo (B5254T2 известен)→1275810 без оговорки. `orchestrator.py.bak-enghonesty-*`.

Проверка live: Kia Optima US-VIN: суппорт 58210-3Z100 / шкив генератора **37322-2G500** / щётки+ремкомплект суппорта честно пусто / комплект ГРМ 2431223202; Volvo: стартер 8251551 ≠ реле 8111635. 975 passed. Связано [[avtero_named_canonical_gate]] [[avtero_full_coverage_program]].
