Files
akyldash/docs/product/minjust-document-normalization-agent-task.md

11 KiB
Raw Permalink Blame History

Задание агенту: нормализация документов ЦБД Минюста КР

Цель

Реализовать первую рабочую версию воспроизводимого нормализатора локального архива data/minjust-cbd. Нормализованные данные должны быть пригодны для последующей загрузки в OpenSearch, backend API и RAG, но подключение этих сервисов в текущую задачу не входит.

Текущее состояние

  • загрузчик находится в backend/ingestion/minjust_cbd.py;
  • сырой архив хранится в data/minjust-cbd и исключён из Git;
  • в манифесте 209 811 успешно загруженных документов;
  • 13 кодов остаются в таблице errors и отсутствуют в таблице documents;
  • документ содержит metadata.json и каталог editions;
  • редакция содержит metadata.json, ru.html и/или ky.html, иногда изображения;
  • HTML создан Microsoft Word, может содержать некорректный <meta charset=unicode>, служебные стили и неполную разметку;
  • файлы архива записаны загрузчиком в UTF-8;
  • часть документов одноязычная, а часть не содержит HTML-текста.

Обязательные ограничения

  1. Не изменять и не перезаписывать data/minjust-cbd.
  2. Не запускать полный проход по архиву во время автоматических тестов.
  3. Не подключать PostgreSQL, OpenSearch, OCR, embeddings, машинный перевод и сетевые API.
  4. Сначала использовать стандартную библиотеку. Новая зависимость допустима только если на реальных образцах доказано, что стандартный HTML-парсер не обеспечивает корректность или безопасность.
  5. Все записи выполнять атомарно.
  6. Ошибка одного документа не должна останавливать длительный прогон.
  7. Повторный запуск должен пропускать неизменившиеся документы.
  8. Не изменять пользовательские файлы logs/, исходный DOCX и несвязанные незакоммиченные изменения.

Размещение

Использовать существующую backend-структуру:

backend/
  normalization/
    minjust_cbd.py

Результат по умолчанию:

data/minjust-normalized/
  manifest.sqlite3
  documents/<document_code>/document.json
  documents/<document_code>/editions/<edition_code>/edition.json
  documents/<document_code>/editions/<edition_code>/<lang>/content.html
  documents/<document_code>/editions/<edition_code>/<lang>/content.txt
  documents/<document_code>/editions/<edition_code>/<lang>/fragments.json

Каталог уже покрывается правилом игнорирования data/.

Канонические данные

document.json

Сохранить как минимум:

  • schema_version;
  • source_code;
  • двуязычные class, type, title, name, status;
  • номера и даты без юридически неподтверждённых выводов;
  • флаги публичности;
  • органы, публикации, ключевые слова и классификаторы с сохранением дерева;
  • пути листьев иерархий для будущих фильтров;
  • ссылки из References без выдумывания связей;
  • available_languages;
  • список редакций;
  • путь к источнику и SHA-256 исходных файлов;
  • версию нормализатора и время обработки.

Пустые строки привести к null, но не переводить значения и не заменять официальные формулировки собственными.

edition.json

Сохранить:

  • исходный код редакции;
  • двуязычное название;
  • исходный тип;
  • доступные языки;
  • изображения без бинарных данных;
  • контрольные суммы источников;
  • признаки качества.

Не считать дату из Name датой вступления редакции в силу и не назначать актуальную редакцию без подтверждённого правила источника.

Языковой вариант

Для каждого имеющегося ru.html или ky.html сформировать:

  • content.html — безопасный HTML для frontend;
  • content.txt — извлечённый текст с сохранением смысловых переносов;
  • fragments.json — упорядоченные адресуемые блоки.

Сырой HTML всегда читать как UTF-8, не доверяя его meta charset.

Очистка HTML

  • удалить script, style, meta, link, комментарии и служебные элементы;
  • удалить обработчики событий, inline-стили и опасные URL;
  • разрешить минимальный набор структурных тегов: заголовки, абзацы, pre, списки, таблицы, безопасные ссылки, изображения и базовое текстовое выделение;
  • нормализовать Unicode в NFC;
  • преобразовать неразрывные пробелы и избыточные пробелы только в content.txt, не искажая отображаемый юридический текст;
  • не загружать внешние ресурсы;
  • относительные изображения связывать только с файлами внутри редакции;
  • неизвестную или сломанную разметку сохранять как текст, а не терять молча.

Фрагменты

Минимальная версия должна создавать фрагмент для каждого содержательного блочного элемента. Распознавание статей и пунктов допускается только простыми проверяемыми правилами RU/KY; обычный абзац является fallback.

Каждый фрагмент содержит:

  • стабильный id;
  • document_code, edition_code, language;
  • порядковую позицию;
  • тип блока;
  • чистый текст;
  • SHA-256 текста.

Идентификатор должен быть детерминированным и включать документ, редакцию, язык и позицию. Не добавлять сложное сопоставление фрагментов между редакциями — это отдельная будущая задача.

Манифест и возобновление

SQLite-манифест должен хранить:

  • код документа;
  • SHA-256 набора исходных файлов;
  • версию схемы и нормализатора;
  • время успешной обработки;
  • состояние и текст последней ошибки.

Если checksum и версия нормализатора не изменились, документ пропускается. После успешной повторной обработки ошибка удаляется. Добавить --limit и понятный терминальный прогресс, пригодный для долгого запуска.

CLI и импорт из будущего backend

CLI запускается из корня репозитория:

python3 backend/normalization/minjust_cbd.py

Предусмотреть параметры:

  • --input;
  • --output;
  • --limit;
  • --refresh;
  • --log-level.

Основную функцию можно импортировать без запуска CLI. Не создавать планировщик, очередь задач или framework-интеграцию.

Проверки

Добавить один компактный тестовый модуль, который проверяет:

  1. русскую редакцию;
  2. кыргызскую редакцию;
  3. двуязычную редакцию;
  4. Word HTML с опасным script, inline-стилем и javascript: URL;
  5. документ без HTML;
  6. повторный запуск и пропуск неизменившегося документа;
  7. продолжение после ошибки одного документа;
  8. детерминированные fragment ID и checksums.

Провести пилотный read-only запуск на небольшой реальной выборке через --limit, не нормализовать весь архив в рамках разработки.

Документация и версия

  • описать запуск, структуру результата и ограничения в backend/README.md;
  • отметить реализацию в docs/operations/project-status.md;
  • это новая обратно совместимая backend-функция: увеличить minor-версию backend по SemVer;
  • обновить все отображаемые backend-версии и footer, не меняя версию Telegram-бота;
  • frontend по-прежнему помечать как не созданный.

Критерии приёмки

  • сырой архив не изменён;
  • тесты проходят;
  • git diff --check проходит;
  • пилотный запуск завершается без остановки на отдельных ошибках;
  • повторный пилотный запуск пропускает неизменившиеся документы;
  • unsafe HTML не попадает в content.html;
  • каждый фрагмент прослеживается до документа, редакции, языка и исходного файла;
  • отсутствуют молча потерянные HTML или ошибки;
  • реализация не содержит PostgreSQL/OpenSearch/RAG-кода «на будущее».

Акылдаш · Telegram-бот v0.2.2 · Backend v0.7.1 · Frontend — не создан