4665c537e8
extractCandidates грузила в primary_rationale.candidates_considered ЛЮБОЙ нумерованный/маркированный список из ассистентского текста — без семантического фильтра. В topе оказывались куски прозы («Hard-floor работает только для §12 Superpowers …»), шаги процедуры («1. Hard-floor check, 2. Классификация …»), фрагменты кода (regex-паттерны) — не имена узлов реестра. Фикс: при загрузке модуля собираю KNOWN_NODES из tools/observer-known-nodes.txt + ключей observer-chain-map.json + сентинела «direct». После regex-извлечения item нормализуется (срезаются **/`/_/* обвязки + хвостовая пунктуация) и проверяется по: точное имя в реестре ИЛИ #NN (Tooling ID) ИЛИ plugin:skill форма. Если после фильтра <2 элементов — return []. Opt-in <!-- reasoning --> тег остаётся authoritative и идёт мимо фильтра. Триггеры/границы не трогал — их regex уже узкий (Pravila §N / ADR-N / PSR_v1 RN / L-цепочки). Repro-кейсы из живого episodes-2026-05.jsonl добавлены в тесты: prose-bullets, procedure-steps, code-snippet bullets, mixed list, single survivor.