| name | intake |
| description | Приём и систематизация первичных материалов от клиента по судебному делу. Используй этот скилл, когда юрист загружает документы по делу, говорит «вот материалы от клиента», «разбери эти файлы», «обработай документы», «приобщи материалы», «принял пакет документов от клиента», или когда в `Входящие документы/` появляются файлы, которые нужно разложить по хронологии, переименовать, создать md-зеркала и обновить индекс. Скилл обрабатывает pdf, docx, изображения, сканы, архивы (zip/rar/7z/tar). НЕ используй для документов оппонента (это `add-opponent`) и для дополнительных доказательств в ходе дела (это `add-evidence`, хотя алгоритм похож).
|
Intake — Приём материалов клиента
Скилл работает по контракту plan → review → (revise) → apply → verify. Оркестрацию ведёт main-Sonnet: он читает метаданные дела, запускает локальные скрипты, пишет план, обновляет .vassal/index.yaml и .vassal/history.md, архивирует план и чистит временные каталоги. Механическую классификацию и черновые подсказки по именам/типам main-Sonnet делегирует Haiku-subagent по контракту 3.3A из shared/subagent-dispatch.md.
Main-Sonnet не вставляет в subagent prompt полные тексты исходников. Он передаёт только абсолютные пути и короткие OCR-фрагменты по правилам shared/subagent-dispatch.md и shared/conventions.md.
Предусловия
- Дело инициализировано: существует
.vassal/case.yaml. Если нет — предложи запустить /vassal-litigator-cc:init-case.
- Существует папка
Входящие документы/ и в ней хотя бы один файл. Если папки нет или она пуста — сообщи Сюзерену и останови intake.
- В корне дела существует
.vassal/index.yaml (после init-case гарантированно есть).
- Установлены зависимости (
tesseract, ocrmypdf, unzip, 7z, tar, unrar, Python-пакеты). Если [PLUGIN_ROOT]/scripts/setup.sh на этой машине ещё не запускался — запусти один раз.
- Доступен
Task с model: "haiku" для субагентного вызова по контракту 3.3. Если вызов недоступен — см. раздел «Блокер при недоступном Haiku-subagent».
Переменные сессии
Вычисли один раз в начале intake и используй во всех фазах:
plan_timestamp = текущее ГГГГ-ММ-ДД-ЧЧмм (локальное время машины)
batch_name = intake-ГГГГ-ММ-ДД
plan_path = .vassal/plans/intake-<plan_timestamp>.md
work_dir = .vassal/work/intake-<plan_timestamp>/
next_id_hint = прочитай next_id из .vassal/index.yaml (при отсутствии — 1)
Создай пустые .vassal/plans/ и .vassal/work/, если их нет.
Фаза 1 — Plan (main-Sonnet + Haiku-subagent)
- Прочитай
.vassal/case.yaml, .vassal/index.yaml и список файлов в Входящие документы/. Не показывай Сюзерену сырые тексты документов на этом шаге.
- Подготовь рабочую область
{{work_dir}}, выполнив скрипт:
python3 "$PLUGIN_ROOT/scripts/prepare_intake_workdir.py" "$INCOMING_DIR" --work-dir "$WORK_DIR"
Распарси JSON: поля files[] (каждый элемент: source_path, extracted_text_preview, needs_image_to_pdf, archive_src), archives_unpacked, unsupported. Если unsupported[] не пуст — сообщи Сюзерену о неподдерживаемых или проблемных архивах. Передай список files[] в Haiku-subagent для планирования.
- Для механической классификации собери prompt субагента по контракту 3.3A из shared/subagent-dispatch.md:
ROLE: обработчик файлов в скилле intake;
CONTEXT: case_root, work_dir, список files[] из JSON скрипта (поля source_path и extracted_text_preview);
TASK: вернуть new_name и doc_type;
OUTPUT: чистый YAML-массив file/new_name/doc_type.
- Вызови
Task с параметрами subagent_type: "general-purpose", model: "haiku", description длиной 3-5 слов. Если файлов больше 20 — бей на несколько вызовов, но формат OUTPUT держи одинаковым.
- Main-Sonnet принимает YAML от Haiku, затем сам:
- определяет комплекты, приложения и сироты;
- назначает
doc-ID от next_id_hint;
- определяет целевые пути по
shared/conventions.md;
- помечает
already_processed, если файл уже есть в индексе по origin.name + origin.archive_src + batch.
- Запиши полный markdown-план в
{{plan_path}}. В плане должны быть все сущности, которые пользователь будет подтверждать: таблица файлов, комплекты, сироты без даты, конверсии изображений → PDF, не обработанные архивы, проверки плана.
- Если subagent вернул невалидный YAML — перезапусти его один раз с тем же контрактом и явным указанием вернуть только YAML. Если повторно не удалось — остановись и покажи Сюзерену блокер.
Фаза 2 — Review Сюзереном
- Прочитай
{{plan_path}} целиком.
- Покажи Сюзерену весь план, без пересказа вместо него. Допустим короткий сопроводительный комментарий на 2-3 строки с числами.
- Спроси: «Подтверждаешь? Если есть правки — напиши, что поменять буквально: разделить комплект, переименовать, переместить конкретный файл и т.п.»
- Варианты ответа:
- подтверждение (
ок, apply, go, да) → переход к Фазе 3;
- правки → переход к Фазе 2b;
- отмена → остановить intake, ничего не применяя.
Фаза 2b — Revise
- Возьми буквальный текст правок Сюзерена как
revise_feedback.
- Пересобери план в тех же
{{plan_path}} и {{work_dir}}: заново прогони классификацию через Haiku только для затронутых файлов или пакета целиком, если правки меняют структуру комплекта.
- Вернись к Фазе 2 и снова покажи весь обновлённый план.
Фаза 3 — Apply (main-Sonnet)
Выполняется только после явного подтверждения Сюзерена.
- Прочитай утверждённый
{{plan_path}} и исполни его детерминированно.
- Main-Sonnet сам выполняет файловые операции:
- копирует все исходники в
.vassal/raw/{{batch_name}}/;
- конвертирует изображения в PDF;
- раскладывает документы по
Материалы от клиента/ с сохранением границ комплектов;
- создаёт md-зеркала в
.vassal/mirrors/;
- обновляет
.vassal/index.yaml, next_id, bundle-поля и .vassal/history.md;
- удаляет файлы из
Входящие документы/, активный {{plan_path}} и {{work_dir}}.
- Архив-оригинал остаётся только в
.vassal/raw/ и не индексируется как отдельный документ. Индексируется только его содержимое.
Фаза 4 — Verify (main-Sonnet)
- Прочитай
.vassal/index.yaml и убедись, что новые записи имеют обязательные поля из shared/index-schema.yaml.
- Для каждого нового документа вычисли
ocr_quality/ocr_quality_reason через:
python3 "$PLUGIN_ROOT/scripts/classify_ocr_quality.py" --extraction-method <extraction_method> --confidence <confidence> --total-chars <total_chars> --pages <pages> и подставь результат в поля записи. Если total_chars или pages неизвестны или отсутствуют, передавай значение "" или "null" — скрипт обработает их как None и не упадёт.
- Для этого этапа отдельный
reocr ещё не запускался: если повторной попытки не было, фиксируй ocr_reattempted: false.
- Если
ocr_quality получилось low или empty, не скрывай это в резюме: пометь запись для ручной проверки и покажи причину.
- Проверь, что:
.vassal/mirrors/doc-*.md созданы для всех новых документов;
- в
Входящие документы/ не осталось файлов из утверждённого плана;
- активные
{{plan_path}} и {{work_dir}} удалены.
- Покажи Сюзерену финальное резюме:
N файлов обработано, M комплектов, S сирот, K изображений → PDF. ocr_quality low/empty: X.
Примечание: legacy-директория .vassal/codex-logs/ может остаться от дел v0.5.x, но v0.6.0 её не создаёт и не использует; текущий прогон фиксируется через .vassal/history.md.
Имена, папки, идемпотентность
- Формат новых имён, правила хронологической раскладки и политика тематических папок — единый источник:
shared/conventions.md.
doc-ID всегда назначает main-Sonnet, исходя из next_id из .vassal/index.yaml.
- Идемпотентность: если файл уже присутствует в индексе по
origin.name + origin.archive_src + batch, план помечает его как already_processed и apply не создаёт дубликат записи.
Блокер при недоступном Haiku-subagent
Если Task(model=haiku) недоступен, завершился ошибкой или дважды подряд вернул непарсируемый OUTPUT:
- Сообщи Сюзерену:
Haiku-subagent недоступен, intake остановлен. Нужен рабочий Task(model=haiku) по контракту 3.3.
- Покажи конкретную ошибку или причину непарсируемости.
- Не переходи к «ручной» замене классификации в main-Sonnet. Для этого скилла механическая маршрутизация имён и типов закреплена за Haiku-subagent.