Сперанский — составление процессуальных документов
Тяжелое (первичка, практика, позиция) уже сделано агентами — лежит в .agent/context/. Читать кеши, не сырые файлы.
Токен-дисциплина (на всех шагах)
| Правило | Содержание |
|---|---|
| Один Read на файл | Не читать дважды и не вразбивку. Раздел справочника: grep -n "^## §" → ОДИН Read (offset/limit); разделы разбросаны → один Read целиком |
| Кеш роутера | Повторное извлечение запрещено; повторный markdown_extract.py = кеш, 0 токенов |
| Механика — в код | Подсчеты, маркеры, сверка реквизитов, поиск «е» — grep / python3 -c, не рассуждением |
| Подача материалов агенту | До 15 000 токенов — ТЕКСТОМ в промпте агента. Путь — только если агент сам решает, что читать, или материал больше |
| Пакет документов — ОДИН прогон | Несколько документов по одному делу и одной позиции (претензия + иск, иск + ходатайство) составляются последовательно в ОДНОМ прогоне: база (карта, practice.md, positions.md, redlines.md, DOCX_FORMATTING.md) читается один раз. Параллельные прогоны допустимы только по разным делам либо разным позициям — иначе каждый оплачивает одно и то же чтение заново (замер 16.08.2026: два прогона по одному делу — 32% расхода, шаг 4) |
Входной контракт (ДО работы; провал → СТОП)
Первое действие — ОДИН вызов python3 scripts/case_paths.py --document-contract cases/{клиент}/{дело}. Строка blocks обязана разом содержать шесть блоков:
content (содержание), sources (источники), canon (канон формулировок),
form (форма подачи), admission (порядок допуска), home (дом и имя готового
файла). В каждом блоке exists=true, в каждом его источнике указан путь и
exists=true; иначе СТОП с именем блока и отсутствующим путем, без догадки и
повторного запроса контракта.
| № | Что | Проверка | Нет → |
|---|---|---|---|
| 1 | Дело | cases/_index.md → cases/{клиент}/{дело}/ |
спросить, не угадывать |
| 2 | Карта | grep -F "## КАРТА ГОТОВА ✓" .agent/context/knowledge-map.md |
СТОП → Сбои |
| 3 | Уровень/трек | блок ## ОХОТНИКИ — РЕШЕНИЕ ФЕМИДЫ в карте; нет → L2 FAST |
— |
| 4 | Практика | grep -E "^## СОВЕТ ЗАВЕРШ" .agent/context/practice.md (маркер в КОНЦЕ файла) |
послабления, иначе СТОП |
| 5 | Позиция | grep -F "СОГЛАСОВАНО СОВЕТОМ" .agent/context/positions.md |
послабления, иначе СТОП |
Послабления FAST/L1 (по AGENTS.md):
| Уровень · трек | practice.md | positions.md |
|---|---|---|
| L1 | файл есть; маркер ИЛИ «FAST-синтез Фемидой» | не требуется |
| L2 FAST | то же | файл есть; маркер ИЛИ «знаю позицию — /position-council пропущен» в _case.md |
| L2 FULL / L3 / кассация ВС | только маркер | только маркер; для L3 пропуск запрещен |
| 6 | Заморозка фактуры | grep -rF "ФАКТУРА ЗАМОРОЖЕНА" .agent/context/_working/brief.md _case.md | нет брифа вовсе → выписать открытые вопросы по фактуре, показать владельцу, получить «работаем с тем, что есть» и дописать строку ФАКТУРА ЗАМОРОЖЕНА ДД.ММ.ГГГГ в _case.md; вопросы открыты → СТОП |
Пройден → статус: ✓ Контракт: карта · практика · позиция · фактура заморожена. Уровень L{X}, трек {FAST|FULL}. Составляю.
Один запуск на документ. Перегенерация из-за доехавших позже материалов — самая дорогая статья проекта (773 000 токенов за сессию, 54% ее расхода; 285 061 на простом L1). Новые вводные после заморозки вносятся Edit-патчем в готовый черновик: правится абзац, а не пересобирается документ. Полная пересборка допустима только при смене правовой позиции в positions.md — тогда это откат на шаг 3 конвейера, а не повтор шага 4, и он объявляется владельцу.
Новый такт правки открывает только отрицательный вердикт doc-reviewer по
текущей редакции. Новое требование координатора вердиктом не считается: СТОП,
сначала обновить контракт или positions.md, затем передать составителю полный
контракт заново как новый запуск.
Алгоритм
Шаг 1. Redlines (первым, обязателен)
knowledge/redlines.md (один Read целиком): раздел категории документа + «Форматирование» + «Общие предпочтения доверителя». Выписать список - правило → как учту (обычно 3-7); пусто → «redlines: применимых правил нет». Список не записан → шаг не закрыт.
Шаг 2. Кеши дела
Сначала якоря, потом чтение. python3 scripts/case_graph.py ask cases/{клиент}/{дело} "{объект или вопрос}" возвращает узлы с src=.agent/context/knowledge-map.md loc=строка N — читать надо ТОЛЬКО эти строки, а не карту целиком. Формулировка берется ИЗ КАРТЫ по якорю: ребро графа не цитируется ни в документе, ни суду. Прибор отказал (карта без маркера или без разделов 1-4) → работать как раньше, полным чтением: граф ускоряет, но никогда не блокирует составление.
knowledge-map.md, practice.md, positions.md (по уровню) — по одному Read. К 00_intake/ — только за деталью, которой нет в карте: python3 scripts/markdown_extract.py FILE --json-meta → срез из кеша; реквизиты — из готового <sha>.requisites.json. Запрещено: intake подряд; .docx/.pdf/.xlsx через Read; перераспознавать OCR. Выкладки → .agent/context/_working/, не в чат.
Шаг 3. Справочники — выборочно по типу документа
Целиком не читать — только разделы ## §N из таблицы:
| Тип документа | LEGAL_RU_SYSTEM.md | CONTENT_DESIGN.md |
|---|---|---|
| Иск (ГПК/АПК/КАС) | §1, §6 | §1, §2, §4 |
| Отзыв, возражения | §2 | §1, §2 |
| Ходатайство | §3 (+ §6, если облагается) | §1 |
| Апелляция / кассация / надзор | §4, §6 | §1, §2 |
| Семейные дела | §5, §1, §6 | §1, §2, §4 |
| Досудебный (претензия) | §7 | §2, §5 |
Дополнительно: CONTENT §3 — несколько ответчиков или госорган; CONTENT §5 — перед подписью; DOCX_FORMATTING.md целиком — перед Шагом 8.
Пошлина: считать python3 scripts/gosposhlina.py --cena N либо --neimushchestvennyy --status fiz|org (арбитраж — --sud arbitrazh, приказ — --prikaz). Скрипт берет шкалу разбором ст. 333.19/333.21 из корпуса и печатает дату редакции; статус заявителя — обязательный аргумент, поэтому перепутать колонку физлица и организации конструктивно нельзя (урок 23.07.2026). Руками и «по таблице из справочника» не считать. Льготы ст. 333.35-333.36 скрипт не применяет — проверять отдельно.
Шаг 4. Позиция
- L2/L3: основа —
positions.md, адаптировать под тип документа. L1/FAST без него — из карты + practice.md. - Сужение пакета требований против positions.md — ТОЛЬКО с решением, записанным в positions.md (кто, почему, дата); иначе Кони вернет (урок 23.07.2026).
- Аргументы: каждый вытекает из предыдущего; факты только из карты; каждому доводу оппонента — контрдовод; сильнейший — последним перед просительной частью.
- Доля в имущественных делах — ПО КАЖДОМУ ОБЪЕКТУ отдельно; единая «на все» — только с прямым подтверждением из материалов.
Шаг 5. Анти-галлюцинация (на всех шагах)
- Каждое правовое утверждение — источник прямо в тексте:
(ст. 333 ГК РФ),(Пленум ВС РФ от ДД.ММ.ГГГГ № X, п. Y),(дело № А65-XXXXX/2024). Нет источника → не включать.- Квадратные скобки запрещены (решение владельца 10.08.2026) — только круглые. Хорошо:
Неустойка несоразмерна (ст. 333 ГК РФ; Пленум ВС РФ от 24.03.2016 № 7, п. 71).Плохо:Суды обычно снижают неустойку.— источника нет. - Текст нормы брать из корпуса, не из памяти:
python3 scripts/cite.py "ст. 333 ГК"(или"п. 71 Пленума ВС РФ от 24.03.2016 № 7"). На диске 17 кодексов и ФЗ плюс 329 Пленумов, сеть не нужна, $0. Код возврата 2 — редакция неизвестна или подозрительна: такую цитату в документ НЕ вставлять без сверки с pravo.gov.ru. Код 3 — корпус поврежден, СТОП. Прецедент: пересказ ст. 683 ГК РФ по памяти инструмента исказил текст на боевом деле. - Кодекса нет в корпусе (
cite.py --list) — норму цитировать только с проверенного публикатора и пометить в отчете, откуда взята. - Пересказ нормы сверяется с корпусом (
cite.py) наравне с цитатой и не вправе расширять ее объем. Пересказ, свободный от кавычек, все равно связан объемом нормы: сказать больше, чем сказано в законе или Пленуме, запрещено так же, как исказить цитату (рецензент бракует пересказ шире нормы — прецедент 25.08.2026: п. 8 ст. 448 ГК РФ и п. 45 Пленума ВС РФ № 49 забракованы два круга подряд). При сомнении, укладывается ли пересказ в объем нормы, норма приводится дословной блок-цитатой из корпуса.
- Квадратные скобки запрещены (решение владельца 10.08.2026) — только круглые. Хорошо:
- Реквизиты актов — только из practice.md / hunter-файлов, не из памяти. Не подтверждено →
требует проверки. - Цитаты КС РФ / Пленумов — дословно и целиком из
.agent/context/_practice/hunter_*.mdили первоисточника; купюра только с(...); сжатие по памяти запрещено (урок 23.07.2026, КС № 35-П). - Ссылки на КС/Пленумы из внешних документов — сверить по ksrf.ru / vsrf.ru ДО заимствования; подмена → предупредить доверителя.
Шаг 6. Черновик .md
Структура .md: факты → правовая позиция (доводы → нормы → практика) → просительная часть → приложения → дата документа, если она не дублирует шапку сборщика. Содержание — по разделам CONTENT из Шага 3. Язык — /humanizer: живой официально-деловой; без «е»; даты ДД.ММ.ГГГГ; понятен неюристу.
Один черновик, не версии. Файл — .agent/drafts/{документ}.md, перезаписывается на месте на каждой правке. Никаких _v1, _v2 и сквозной нумерации: девять версий за прогон кормят шумом quality_gate и рождают вопрос «какая редакция последняя» (прецедент 25.08.2026). История редакций — в git, он уже есть; предыдущая редакция при необходимости уезжает в .agent/drafts/_working/history/, но собирается и рецензируется всегда один и тот же файл.
Служебные элементы в .md НЕ входят. Адресная шапка (суд, № дела, стороны в правой половине листа), строка подписи и колонтитулы — служебные элементы, их ставит DocBuilder при сборке. В одобряемый рецензентом .md они не пишутся: писать шапку внутри .md — брак, который рецензент вернет на изъятие (прецедент 25.08.2026: шапка внутри .md пять редакций подряд, целый круг ушел на ее удаление). В черновике .md — только тело документа: факты, правовая позиция, просительная часть, приложения, дата.
Шаг 7. Guard: правки доверителя (перед сборкой .docx)
Целевой .docx уже существует →
cmp -s ФАЙЛ .agent/drafts/_baselines/{имя}.docx; echo $?→1= различаются.officecli get ФАЙЛ.docx /revision— правки с авторами (первым); фолбэкunzip -p ФАЙЛ.docx docProps/core.xml | grep -oE "(lastModifiedBy|revision)>[^<]*".- Правки доверителя → СТОП, не перезаписывать; предложить redline-разбор («изучи мои правки по {дело}»).
save()дублирует guard безусловно, env-обхода нет (этап 9, урок 14.07.2026).
Шаг 8. Приборы исполнителя, затем раунд Кони по .md — ДО сборки
Приборы гоняет исполнитель, до рецензии. До вызова doc-reviewer прогнать по своему .md три прибора и приложить их вывод И коды к сдаче:
scripts/gate.sh python3 scripts/document_guard.py --md-only ЧЕРНОВИК.md; rc_guard=$?
scripts/gate.sh python3 scripts/quality_gate.py --doc ЧЕРНОВИК.md --against .agent/context/knowledge-map.md .agent/context/practice.md .agent/context/positions.md; rc_gate=$?
scripts/gate.sh bash .claude/skills/humanizer-legal/scripts/scan_legal.sh ЧЕРНОВИК.md; rc_scan=$?
Правила вызова, без которых прибор не работает ни в одну сторону (каталог №16 и №21):
- Код читается сразу после вызова прибора (
rc=$?), никогда после трубы.$?после| tail/| head— код последней команды трубы (всегда 0), а не прибора: так «итого замечаний: 1» легло рядом с «код: 0» восемь раз за прогон. Нужны и вывод через трубу, и код —${PIPESTATUS[0]}. quality_gate: источники чисел передаются явно через--against, и только существующие файлы —knowledge-map.mdвсегда,practice.md/positions.md— когда на этом уровне есть (несуществующий источник = замечание, код 1). Без источников прибор падает с кодом 2 и черновик не проверен;--caseздесь не использовать — безquality_gate.jsonв деле он всегда дает код 1 поconfig.policy.- Код 2 — прибор НЕ ОТРАБОТАЛ (ошибка разбора аргументов, сбой), это не вердикт и не прохождение. Две usage-ошибки в финале 25.08.2026 приняли за прохождение, и последняя редакция ушла непроверенной ни одним прибором. Код 2 → СТОП, вызов чинится по
--helpприбора, не по памяти.
Черновик с ненулевым кодом любого из трех к рецензии не принимается: исполнитель правит свой .md и гоняет приборы заново, пока все три не дадут 0. Раунда Кони по машинному замечанию не существует — рецензент судит то, что машина уже пропустила: формальные дефекты машина ловит раньше и дешевле (прецедент 25.08.2026: изъятие шапки и пропись у сумм — оба замечания машинные, всплыли после одобрения смысла и стоили трех кругов). Свод машинных требований печатает сам прибор — python3 scripts/document_guard.py --rules, звать его ДО письма, а не узнавать правила от рецензента.
Сборщик не соберет .docx без вердикта: save() отказывает словами «СТОП, НЕ
СОХРАНЕНО: сборка .docx запрещена вердиктом». Поэтому проверка идет по черновику
.md, и только одобренный текст превращается в документ.
Запустить doc-reviewer: в промпт — ТЕКСТ черновика целиком (правило подачи
материалов) + путь к делу + примененные redlines + вывод трех приборов; Кони не
перечитывает справочники и кеши и не гоняет приборы заново — читает приложенный
вывод. Число раундов ограничено лимитом review_rounds — актуальное значение
печатает python3 scripts/case_paths.py --document-contract:
Резерв, если инструмента Agent нет или он отказал. Не ждать
недоступного Claude и не звать doc-reviewer через внешний CLI: это роль класса
pd, и foreign_cli.py законно ее отобьет. Собрать один обезличенный
cases/{клиент}/{дело}/.agent/drafts/_working/review-packet.redacted.md: полный стабильный текст
черновика; нужные для его проверки выписки из карты, positions.md, practice.md
с их локальными ссылками; примененные redlines; вывод и коды трех приборов; задание
проверить весь документ одним проходом по трем линзам Кони и вернуть ровно один вердикт
из словаря ниже. Краткий вопрос, обрывки документа или пакет без этих источников
полной рецензией не считаются. Пакет обезличить через pii_gate.py --mask, затем вызвать:
python3 scripts/foreign_cli.py --role second-opinion \
--prompt cases/{клиент}/{дело}/.agent/drafts/_working/review-packet.redacted.md \
--timeout 180 --out cases/{клиент}/{дело}/.agent/drafts/_working/review-response.md
Провайдера и модель выбирает реестр: --provider не передавать. Прямой вызов codex
запрещен: явный набор допусков задает foreign_cli.py — временный каталог с одним
обезличенным пакетом, read-only песочница, без запроса разрешений. Команда проверена
08.09.2026 живым вызовом: second-opinion выбрал Codex gpt-5.6-sol, effort high,
вернул содержательную рецензию и код 0. Эта техническая проба подтверждает
запуск отдельного процесса, но не готовность любого юридического текста.
Ответ со всеми тремя линзами координатор связывает с исходным документом, после
чего пишет вердикт через verdict.py --record --source coordinator. После записи обязателен
python3 scripts/swarm_contract.py --review-verdict ЧЕРНОВИК.md cases/{клиент}/{дело}/.agent/drafts/verdicts.jsonl.
Неполный ответ, ошибка CLI, пустой ответ или ненулевой код → СТОП без записи
вердикта. Запись ПРОВЕРЕНО БЕЗ КОНИ (...) запрещена: это пометка об отсутствии
рецензента, и swarm_contract.py ее отвергает.
- «ГОТОВ К ПОДАЧЕ» → записать вердикт и идти на Шаг 9:
python3 scripts/verdict.py ЧЕРНОВИК.md --record --verdict 'ГОТОВ К ПОДАЧЕ' -r N - «ТРЕБУЕТ ПРАВОК» → внести правки в тот же файл → повторный раунд (вердикт отзывается, сборка снова закрыта);
- «ПРОВЕРЕНО ЧАСТИЧНО» → СТОП: назвать несверенные цитаты/пересказы, без
.docx; - «КРИТИЧЕСКИЕ ОШИБКИ» или лимит раундов исчерпан без одобрения → СТОП, разногласия пользователю списком.
Отчет проверки — .agent/drafts/_working/review_log.md, строка на раунд.
Вердикт обязан быть ОТДЕЛЬНЫМ артефактом рецензента: фраза «ГОТОВ К ПОДАЧЕ»
в теле самого черновика вердиктом не считается.
Шаг 9. Сборка .docx — только DocBuilder
Контракт сборки (четыре факта, нарушение любого = отказ save()):
- Сборка
.docx— только черезDocBuilder(scripts/create_docx.py). Голый python-docx, шаблоны, ручной XML, универсальные конвертеры — запрещены. - Служебные элементы (адресная шапка, строка подписи, колонтитулы) в одобренный
.mdне входят — их ставит самDocBuilder. Собирать их из.mdне нужно. - Собранный текст обязан совпадать с одобренной редакцией по ВСЕМ единицам:
save()сверяет.docxс одобренным.mdи отказывает при расхождении хоть на одном слове. - Заголовок просительной части в письмах контрагенту — «ПРОСИМ», а метод
add_proshyu()по умолчанию пишет «ПРОШУ» и для писем не годится: тип документа передается аргументом метода (заявление в суд — «ПРОШУ», письмо контрагенту — «ПРОСИМ»). Несовпадение слова роняет сверку из п. 3 (прецедент 25.08.2026:docx: прошу: | md: просим:).
Выбор метода под ситуацию — DOCX_FORMATTING §2, значения не переизобретать:
from scripts.create_docx import DocBuilder
b = DocBuilder() # параметры зашиты; методы по DOCX §2: шапка → заголовки → тело → просительная часть (тип документа аргументом: «ПРОШУ» для суда, «ПРОСИМ» для письма) → приложения → подпись
b.save("cases/.../GOTOVO/{документ}.docx") # авто: «е»→«е», baseline в .agent/drafts/_baselines/
Перед save() — обязательный прогон скилла humanizer-legal по тексту документа. save() его дублирует машинно: гонит текст через scan_legal.sh и НЕ сохраняет файл, если сработала блокирующая категория — HARD BANS, плейсхолдер, артефакт копипасты, невидимые символы, латиница в кириллице. Стоп на этом месте означает, что скилл не прогоняли или прогнали формально: снять маркеры и повторить. Гейт безусловный, env-обхода нет (этап 9): нет скрипта скилла — verdict.py --scan тоже стоит, а не молчит.
После save() проверить: файл создан в GOTOVO/ И снимок появился в .agent/drafts/_baselines/.
Готовый .docx живет в GOTOVO/, и только там. Это единственная папка, за которой владелец приходит за результатом: case_paths.py называет ее «то, за чем человек приходит». Документ, оставленный в .agent/drafts/, для владельца не существует — прецедент 01.09.2026: конвейер отчитался «готово, вот файл», путь вел в служебную папку, GOTOVO/ была пуста, и владелец сообщил, что это уже не первый такой случай. В .agent/drafts/ остаются только рабочий .md и снимок в _baselines/.
Код сборки — только внутри дела, никогда в scripts/. Понадобился одноразовый python-файл под конкретный документ — он живет в cases/{клиент}/{дело}/.agent/context/_working/, которая закрыта .gitignore. Папка scripts/ публикуется в открытый репозиторий, а такой файл несет ФИО, адреса, ИНН и суммы доверителя строковыми литералами. Прецедент 02.08.2026: 16 генераторов на 506 КБ с персональными данными пролежали в публичном репозитории, чистились переписыванием истории.
Шаг 10. Формат и передача
Собранный документ проверить прибором: python3 scripts/document_guard.py ДОКУМЕНТ.docx --md ЧЕРНОВИК.md. Код 0 — принято, код 1 — переделка по списку.
Дальше финализация по Контракту вывода.
Контракт вывода
| Артефакт | Путь | Когда |
|---|---|---|
| Черновик | .agent/drafts/{документ}.md (один файл, перезаписывается) |
всегда |
| Word | GOTOVO/{документ}.docx (DocBuilder) — папка, за которой приходит владелец |
всегда |
| Копия текста | GOTOVO/{документ}.md рядом с Word |
всегда |
| Снимок ДО | .agent/drafts/_baselines/{документ}.docx (кладет save(), проверить) |
всегда |
| Поданный пакет | 02_hearings/ДД-ММ-ГГГГ_название/{документ}.md + .docx |
ТОЛЬКО после подачи в суд |
Рабочий .md остается в .agent/drafts/, готовый документ — в GOTOVO/. Отчитываться владельцу путем в .agent/drafts/ запрещено: для него это не результат. События нет → /new-event; заседание неизвестно → оставить. После финала обновить _event.md и _case.md. PDF с подписью → /finalize {docx}.
Документ ушел в финал → python3 scripts/themiz_bot.py --notify-doc {путь_к_docx} (секрета бота нет — молча пропустить, конвейер от бота не зависит; имя документа и дело наружу не идут, ссылка непрозрачна).
Сбои: ситуация → действие
| Ситуация | Действие |
|---|---|
Нет ## КАРТА ГОТОВА ✓ |
СТОП: «❌ Карта не готова. Запусти case-mapper» |
| practice.md нет / без маркера (FULL) | СТОП: «❌ practice.md не готов. FAST/L1: охотник + синтез Фемидой; FULL: /askacouncil» |
| positions.md нет / без маркера (L2 FULL, L3) | СТОП: «❌ positions.md не согласован → /position-council» (L2: либо «знаю позицию» в _case.md) |
| Деталь/реквизит не подтвержден (карта, кеши, practice/hunter) | не выдумывать: требует проверки, при необходимости запросить у доверителя |
| .docx отличается от baseline (Шаг 7) | СТОП, предложить redline-разбор |
| Прибор исполнителя (Шаг 8) вернул ненулевой код | код 1 — исправить черновик и перегнать приборы до передачи Кони; код 2 — прибор не отработал: СТОП, чинить вызов по --help; к рецензии черновик с браком не принимается |
create_docx.py упал |
сверить с DOCX_FORMATTING, повторить; 2 неудачи → СТОП с ошибкой |
| Кони: критика / нет одобрения | исправить все в том же файле → повторный раунд; лимит раундов (review_rounds из python3 scripts/case_paths.py --document-contract) исчерпан → СТОП: разногласия списком |
| Сузить пакет против positions.md | сначала запись решения в positions.md, потом сужение |
Молчаливая деградация запрещена: любой сбой — фолбэк из таблицы либо СТОП с причиной.
Самопроверка перед возвратом (по диску, не по памяти)
- Перечитать сохраненный
.mdс диска (один Read). - Выборочно 5 правовых утверждений — у каждого источник в круглых скобках.
- Цитаты КС/Пленума дословны (hunter-файлы); купюры только
(...); пересказ не шире нормы (сверенcite.py). grep -c "е" файл.md→ 0; даты только ДД.ММ.ГГГГ.- Пошлина: колонка по статусу заявителя, расчет по LEGAL §6 показан.
- Правила redlines Шага 1 — каждое учтено.
- Служебных элементов (шапка, подпись, колонтитулы) в
.mdнет; раскладка результата — по контрактуpython3 scripts/case_paths.py --document-contract: черновикdraft_md, готовыеready_docx+ready_md, снимок в_baselines/. - Вывод трех приборов Шага 8 приложен, код каждого нулевой.
- Имущественное дело → доля по каждому объекту отдельно.
Пункт не прошел → исправить и повторить. Сырое не возвращать.