lct-hack/scenarios/fire-apartment-l2.yaml
Ivan Gerasimov 7212251112 feat: классификатор ЕКП — признаки вместо выбора службы (lct-32)
Оператор системы-112 службу не выбирает: он проставляет формализованные
признаки происшествия, комбинация признаков даёт код ЕКП, а коду соответствует
список оповещения, который система собирает сама (docs/spec/DATASET.md).
Прежняя модель с полем dds из пяти значений оценивала действие, которого
в боевой работе нет.

- scripts/import_ekp.py (make ekp): книга заказчика → app/domain/ekp.json,
  1283 кода, 61 служба, 23 группы. Разовый импорт, результат под гитом:
  читать xlsx в рантайме — лишняя зависимость и полсекунды на старте.
- domain/ekp.py: справочник с ленивой загрузкой, каскад значений признаков,
  список оповещения с модификаторами (нет доступа, угроза людям, пострадавшие,
  газификация и ещё десяток).
- КИО: поля signs, incident_code, notify. Последние два только на чтение
  и пересчитываются при каждой правке признаков; добавленная вручную служба
  не теряется, удалить службу нельзя — как в боевом АРМ.
- GET /api/ekp/signs отдаёт один уровень признаков, а не дерево на полмегабайта.
- Карточка на фронте: три каскадных селектора вместо выбора службы.
- Оценка: метрика incident_signs (E2, маршрутизация). Для размеченных сценариев
  dds_choice больше не считается — список оповещения производен от признаков,
  и штрафовать за него отдельно значит наказать дважды за одну ошибку.

Разбор книги оказался основной работой: имя службы лежит то в первой строке
заголовка, то во второй, то склеено с модификатором; «Классификатор МЧС» —
заголовок группы колонок, а не служба. Правила разбора в докстринге импорта.

113 тестов зелёных (14 новых в tests/test_ekp.py), make typecheck чистый.
2026-09-19 20:11:50 +03:00

70 lines
2.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Первый сценарий — тот самый, на котором замыкается вертикальный срез
# (docs/hackathon/CASE-DECISION.md: в первый день один сценарий целиком).
# Формат: docs/spec/SCENARIO-FORMAT.md
id: fire-apartment-l2
title: "Пожар в квартире, паникующий заявитель"
type: fire
level: L2
topics: [fires]
modes: [training, exam, self]
extends: checklists/fire.yaml
# Признаки по классификатору заказчика (docs/spec/DATASET.md). Код и список
# оповещения выводит загрузчик — руками их писать нельзя.
signs: [жилой дом, балкон, открытое пламя]
persona:
base: panic
arc:
- { stage: registration, mood: panic }
- { stage: interview, mood: panic }
- { stage: dispatch, mood: worried }
background:
loop: fire_crackle.mp3
gain_db: -18
first_line: "Алло! Алло! Помогите! Горим! А-а-а!"
facts:
- id: f_address
value: "улица Ленина, 14, квартира 47, 5-й этаж"
reveal_on: { question: q_address }
- id: f_what_burns
value: "горит балкон, дым пошёл в квартиру"
reveal_on: { question: q_what_burns }
- id: f_people
value: "в квартире жена и ребёнок, не выходят"
reveal_on: { question: q_people }
- id: f_smoke
value: "дым идёт в подъезд, на площадке ничего не видно"
reveal_on: { question: q_smoke }
- id: f_gas
value: "плита газовая, вентиль в кухне, перекрыть не успел"
reveal_on: { question: q_gas }
checklist:
- { id: q_address, fact: f_address }
- { id: q_what_burns, fact: f_what_burns }
- { id: q_people, fact: f_people }
- { id: q_smoke, fact: f_smoke }
- { id: q_gas, fact: f_gas }
required_fields:
- address
- floor
- incident_type
- dds
- victims_count
- description
ground_truth:
# incident_type, dds и required_facts выводит загрузчик — писать их здесь запрещено.
# Руками задаются только нормализованные ожидания, которые из текста факта
# кодом не достать.
address: "улица Ленина, 14"
victims: 2
tree:
pregenerated: false