Skip to content

Latest commit

 

History

95 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EditorTeam

Редактура русскоязычных текстов по Hearthstone. Система правит грамотность и шаблонность, не трогая авторский голос — и умеет доказать, что не тронула.


Разработка с AI-агентами

Полный контракт работы агентов находится в AGENTS.md, а проектный набор инженерных скиллов и правила выбора — в .agents/profile.yaml и .agents/README.md. Набор закреплён на конкретной ревизии центрального каталога Manacost Labs и не заменяет редакторские правила из CLAUDE.md, СТИЛЬ.md и ГОЛОС.md.

Идея

Обычный редакторский промпт держится на вкусе: «пиши живо», «не используй канцелярит», «сохраняй стиль автора». Проверить такие указания нельзя, поэтому редактор незаметно подменяет голос автора своим.

Здесь иначе: все решения опираются на замеры корпуса из 49 опубликованных гайдов — 1,67 млн знаков, 16 662 предложения. Если правило расходится с тем, как автор пишет на самом деле, отменяется правило, а не автор.

Актуальное evidence и архив автора разделены:

  • research intelligence определяет, что правильно сказать на текущем patch/meta epoch;
  • corpus intelligence определяет, как это звучит у автора.

В режиме GUIDE источники остаются за кулисами: читатель получает совет, а не пересказ реплеев, HSGuru и Reddit. ANALYSIS и REPORT разрешают статистическую форму.

Так были отменены 6 правил словаря из 12. Словарь требовал менять «винрейт» на «процент побед» — в корпусе 68 против 17. «Лейтгейм» на «позднюю игру» — 199 против 8. «Добор» на «взятие карт» — 243 против нуля.


Что умеет

Инструмент Задача
markers.py 30 маркеров шаблонного текста в трёх уровнях: убрать / переписать / смотреть
soul.py детектор живого — следит, чтобы правка не вычистила голос
rhythm.py разброс длин предложений против авторской нормы
cards.py сверка названий карт с локализацией, с морфологией
structure.py состав и порядок разделов гайда, охват матч-апов
consistency.py согласованность внутри текста: разнобой, спорные советы, числа
echo.py перекличка с архивом: где автор писал об этом раньше
precedent.py как автор пишет это слово на самом деле
archive.py сводный аудит всех гайдов сразу
report.py отчёт о правке: что изменилось и на сколько
author.py балл 0–10: соответствие текста авторской норме
selftest.py регрессия правил по корпусу
guide_voice.py не пропускает research-report tone в GUIDE
clarity.py проверка понятности статьи: роли терминов, тезис и нагрузка текста
certainty_guard.py не даёт LOW/MEDIUM claim стать категоричным
semantic_diff.py ловит смену отрицания, чисел и Guide Claim Contract
rewrite_gate.py затвор переплавки: результат против нормы автора, а не против исходника
claims.py утверждения исходника и их покрытие: карты, советы, отрицания, классы
elegance.py аккуратность: номинализации, серии начал, конкретика
evalscore.py оценка переплавки по кейсам tests/evals/

Переплавка

Правка бережёт авторский текст. Но если на входе ИИ-слоп или канцелярит, беречь нечего: исходник становится источником фактов, а форма строится заново — по скелету жанра из профиля и по манере автора из корпуса.

editor-team claims исходник.md                                   # что обязано выжить
editor-team outline validate план.json --source исходник.md      # план: полнота и невыдумывание
editor-team validate-edit исходник.md результат.md --depth переплавка --declared-missing matchups
python3 tools/run_evals.py --inputs-only                         # 16 кейсов: слоп должен проваливаться
# с настоящей моделью — ночной воркфлоу «Ночные эвалы переплавки» (нужен секрет EDITOR_API_KEY)

В шлюзе — "mode": "переплавка" или первое слово сообщения. Два прохода: план (JSON, проверяется сайдкаром) и проза по плану; затвор сравнивает результат с нормой автора и с утверждениями исходника. Раздел без материала не выдумывается, а честно объявляется отсутствующим. Пороги стоят за краем корпуса: затвор не отвергает опубликованные гайды, это проверяет selftest.py.

Evidence-hidden затвор

editor-team audit guide.md --mode GUIDE
editor-team audit analysis.md --mode ANALYSIS
editor-team validate-edit before.md after.md \
  --claims-before claims.json --claims-after claims-after.json \
  --current-patch 36.4 --current-meta-epoch 2026-08-31

FACTUAL_SEMANTIC_DRIFT, CERTAINTY_DRIFT и STALE_EVIDENCE отклоняют правку. Исходные source/replay данные не попадают в промпт редактора: только claim_id, meaning, confidence, patch и meta_epoch.

Continuous Corpus Learning

# снача candidate: baseline не меняется
editor-team corpus add guide.md --published-at 2026-08-30 --patch 36.4

# только явное решение человека активирует текст
editor-team corpus approve GUIDE_ID
editor-team corpus reject GUIDE_ID

editor-team corpus inspect
editor-team corpus versions
editor-team corpus compare v1 v2
editor-team corpus rollback v1

# отдельный исторический архив Полей сражений из TXT
editor-team corpus import-bg "/path/to/гайды по полям"
editor-team corpus inspect --collection bg

# обычные гайды: полный учёт файлов и дедупликация против PDF-корпуса
editor-team corpus import-guides "/path/to/old-koloda-articles-guides"
editor-team corpus inspect --collection archive

Каждая активация считает global и genre baseline, robust statistics, показывает before/after и drift, а затем запускает regression на candidate state. Manifest активируется атомарно только после PASS. TXT-архивы импортируются пакетно, не меняют исходники и по умолчанию остаются candidate + historical/style_only, без права подтверждать текущую мету и менять baseline до ручного approval.

В архиве old-koloda-articles-guides учтены все 348 файлов: 297 уникальных гайдов добавлены как candidates, 49 PDF/TXT-дублей отсеяны, 2 служебных файла пропущены, ошибок нет. Подробнее — docs/corpus-learning.md.

Память архива

Обычный редактор видит только тот текст, который перед ним. Здесь при правке поднимается архив: echo.py находит места, где автор писал о том же, и задаёт три вопроса — не противоречит ли новое старому, одинаково ли названы одинаковые вещи, не переписывается ли заново то, что уже сформулировано.

Поиск идёт по редким словам — названиям карт и архетипов, а не по «колоде» и «мете», — и требует минимум двух общих редких слов: одно бывает случайностью. Индекс на 3930 абзацев строится за десятые доли секунды, без внешних зависимостей.

Аудит архива

archive.py прогоняет все проверки по всем гайдам сразу. На корпусе он нашёл в уже опубликованном:

── АПОСТРОФ в названии (25 в 3 видах)   — чинить в первую очередь, проверка точная
  «Зул’джин» → «Зул'джин»  ×12
  «КелТузад» → «Кел'Тузад»  ×7
  «Аралон»   → «Ара'лон»   ×6

── ТИРЕ в названии (15 в 2 видах)
  «Алдор - искатель истины» → «Алдор – искатель истины»  ×14

Плюс 119 расхождений в регистре, 14 гайдов с ровным ритмом и 2 с дырами в структуре. Находки, вызванные переносами строк при извлечении из PDF, помечаются отдельно и в итог не идут.

Детектор живого

Обычные редакторские метрики измеряют только плохое, и это ловушка: текст можно вычистить до стерильности, и все показатели улучшатся.

soul.py считает противоположное — то, чем автор разговаривает с читателем. Нормы сняты с корпуса, на 1000 слов:

Сигнал Норма Пример
обращение к читателю 11,2 «вы найдёте», «вам будет некогда ждать»
императив читателю 5,1 «оставляйте», «раскапывайте», «не бойтесь»
уступка и поворот 4,2 «Но» в начале, «хотя», «зато»
короткое предложение 7,6 фраза до 8 слов рядом с длинным периодом
скобка с пояснением 1,3 живое отступление

Правило: снижение сигнала требует проверить конкретное изменённое место, но само по себе не делает правку плохой. Жёстко отклоняется только системное выравнивание голоса: когда статья в целом падает ниже нижней нормы. Локально убрать обращение, скобку или короткую фразу можно, если это устраняет доказанную проблему и новый вариант сильнее исходника по смыслу, ясности и пользе для читателя.

Три из пяти сигналов — ровно то, что аккуратный редактор вычищает первым. «Но» в начале склеивает с предыдущим предложением, императив обезличивает в «стоит оставить», уступку с «хотя» вырезает как лишнее хеджирование.

На проверке: живой абзац, «причёсанный» как это сделал бы старательный редактор, потерял обращения 35,7 → 0, императивы 107 → 0, уступки 71 → 0. Ни одного маркера шаблона при этом не появилось — без детектора живого такая правка прошла бы как безупречная.

Как ИИ выбирает правку

У исходника преимущество. Для каждого спорного места редактор сначала называет проблему читателя, затем идёт по лестнице: оставить → исправить локально → переписать. Более сильное вмешательство допустимо, только если меньшее не решает проблему. Кандидат принимается не потому, что стал короче или набрал лучшие метрики, а только если он не хуже исходника по смыслу, логике, конкретике, голосу, жанру и практической пользе — и заметно лучше хотя бы по одному из этих пунктов.

Названия карт

Правило «названия не трогать» защищает от догадок, но не от опечаток. Здесь третий путь: справочник на 6602 карты плюс морфологический разбор через pymorphy3.

Ошибкой не считаются падежные формы («Балинды», «Бранном»), короткие имена («Балинда» вместо «Балинда Каменный Очаг», «Монетка» вместо «Фальшивая монетка») и слова классов и архетипов.

Проверяются апостроф, тире, регистр в многословных названиях — точно, без догадок — и опечатки нечётким сравнением с обязательным совпадением корня.

Найденное в опубликованных текстах: КелТузад без апострофа 7 раз, Зул’джин с кривым апострофом 13 раз, Кельтас вместо Кель'тас.

Согласованность внутри текста

Длинный гайд легко начинает спорить сам с собой. consistency.py ловит три вещи: разнобой в написании («Пират Воин» и «Пират воин», «матч-ап» и «матчап»), карту, которую в одном месте советуют оставлять, а в другом сбрасывать, и заявленное число карт против фактически перечисленных.

Первая проверка надёжная, вторая — подсказка без вердикта: разбирать смысл советов автоматически нельзя, там легко наврать.

Точность далась не сразу. Первая версия дала 24 ложные находки на одном гайде: заглавная после точки считалась разнобоем, названия разделов в заголовках и кавычках — тоже, а однословная карта «К оружию!» ловила любое упоминание оружия. После разбора этих причин на вычитанном корпусе осталось 6 находок на 49 гайдов, и все шесть настоящие.

Общая основа

common.py держит пути, бутстрап .venv, морфологию с кэшем и разбиение текста. Пути раньше считал каждый скрипт сам — и дважды ошибся в числе уровней вверх. В scripts/README.md записано, как добавить новую проверку и на какие грабли уже наступали.

Балл /author

Система принципиально не даёт оценку «текст стал лучше на N%»: такой величины нет. Но одно число всё же считается честно — соответствие авторской норме, из шести измеримых составляющих с открытой формулой.

  5.4 / 10   — соответствие авторской норме

  живое             1.9  ██········  9.6 сигн./1000 сл. при норме 29.4
  ритм              4.2  ████······  разброс/среднее 0.33 при норме 0.51
  чистота          10.0  ██████████  0 маркеров = 0.0/1000 сл.
  названия         10.0  ██████████  0 расхождений с локализацией
  согласованность  10.0  ██████████  0 мест с разнобоем
  структура         3.0  ███·······  1 из 5 разделов, матч-апы 6/11

Шкала откалибрована по корпусу: медиана опубликованных гайдов 9,1, квартили 8,4 / 9,1 / 9,4, минимум 6,9. Десятка не эталон — до неё не дотягивает ни один опубликованный текст.

Под баллом — блок «Что подтянуть». Каждая рекомендация выводится из замера и указывает адрес в тексте:

  живое            ни одного совета глаголом. Безличных оборотов 10,
                   первый — стр. 3: «здесь приходится думать над…»
                   └ в твоих гайдах в таких местах стоит «оставляйте», «держите»

  ритм             самое длинное — 30 слов: «Друид быстро разгоняется…»
                   └ разрубить его надвое дешевле, чем удлинять остальные

  структура        нет разделов: Сборки, Декбилдинг, Муллиган, Стратегия
                   └ в корпусе они есть в 96–100% гайдов

Советов без адреса система не даёт: «пиши живее» и «добавь динамики» запрещены наравне с выдуманным процентом качества. Рекомендация либо опирается на замер и указывает место, либо не выводится. Формулировки при этом остаются авторскими — панель показывает, где смотреть, но не вписывает за автора ни обращений, ни императивов.

Что балл не значит: высокий — не «шедевр», а «написано в твоей манере»; низкий — не «плохо», а «не похоже на корпус», и это может быть осознанным экспериментом.

Регрессия

Корпус — это ещё и тест-набор заведомо хорошего письма. Если правила начинают ругаться на опубликованные тексты, значит они ловят авторскую манеру, а не шаблон.

маркеров всего      303  =  12.2 на 10к слов   (порог 20.0)
живых сигналов      29.8 на 1000 слов          (минимум 20.0)
структура опознана  47 из 49 гайдов (96%)      (минимум 90%)

ОК — правила не задевают опубликованные тексты

Так найдены и сняты четыре дефекта, включая правило про парные тире: 3915 ложных срабатываний, 88% всего шума, и оно прямо противоречило листу стиля, где длинное тире записано как основной знак. Общая частота ложных срабатываний упала со 179,2 до 12,2 на 10 000 слов — в пятнадцать раз.


Устройство

CLAUDE.md              договор редактуры: режимы, закрытый список причин, словарь
ГОЛОС.md               слепок авторской манеры по корпусу
СТИЛЬ.md               решённые вопросы оформления и порядок старшинства правил
гайды/                 корпус: 49 опубликованных гайдов

.claude/skills/
  hs-edit/             редактура
    references/        маркеры, ритм и голос, специфика Hearthstone
    assets/            каталог маркеров, справочник карт
    scripts/           инструменты
  hs-research/         поиск актуального: Reddit, YouTube, мета-сайты

sidecars/nlp/          Natasha + Razdel: offsets, леммы, сущности и повторы
go/internal/hunspell/  подсказки Hunspell с allowlist игровых терминов
go/internal/markdownlint/  безопасный markdownlint CLI-adapter
evals/                 Promptfoo baseline/candidate и 48 обезличенных кейсов

Закрытый список причин

Правка допустима, только если попадает в один из восьми пунктов: ошибка, согласование, двусмысленность, слышимый повтор, тяжёлая конструкция, словарь, абзац-полотно, сломанная логическая связка. Всё остальное остаётся авторским — в том числе то, что редактор написал бы иначе.

Поверх списка работает фильтр четырёх вопросов: удаление, упрощение, речь, информация. Список говорит, когда правка допустима; фильтр — стоит ли она того.

Порядок старшинства

  1. Названия карт и защищённые слова
  2. СТИЛЬ.md — оформление
  3. ГОЛОС.md — мера и ритм
  4. CLAUDE.md — словарь и закрытый список
  5. Общая грамотность

Установка

git clone https://github.com/Manacost-Labs/EditorTeam.git
cd EditorTeam
python3 -m venv .venv && .venv/bin/pip install pymorphy3 pymorphy3-dicts-ru

Готовый ChatGPT Work/Codex plugin лежит в release/editor-team-chatgpt-work-plugin-1.6.0.zip. Повторить сборку с автономной морфологией, corpus и smoke test:

.venv/bin/python tools/build_skill.py --release --проба

Контрольная сумма записана в release/SHA256SUMS.

Чем релиз отстал от исходников, показывает python3 tools/build_skill.py --дрейф. Правило: пока в release/ лежит версия, равная PLUGIN_VERSION в сборщике, содержимое обязано совпадать с исходниками; изменили исходники после релиза — поднимите PLUGIN_VERSION, тест это проверяет.

Морфология нужна только для cards.py — остальные инструменты работают на голом Python 3.

Go-оркестратор

Основной backend запускается из go/:

EDITOR_PROVIDER=none go run ./cmd/editorteam

Он сохраняет /health, /analyze, /validate, /rules и /outline/validate, а новый staged pipeline доступен по POST /v2/edit с режимами proofread, edit и rewrite. Проверки LanguageTool и Vale подключаются через LANGUAGETOOL_URL, VALE_BIN и VALE_CONFIG; старые Python-анализаторы остаются adapter-ом до переноса морфологии. Подробности и пример JSON — в MIGRATION.md и GO_MIGRATION_PLAN.md.

Полный набор внешних проверок поднимается через docker compose up --build: LanguageTool и Natasha/Razdel запускаются отдельными сервисами, а Hunspell, Vale и markdownlint вызываются из Go с таймаутом и ограничением вывода. Если инструмент недоступен, ответ содержит analyzer_unavailable и checks_complete=false — текст не выдаётся за полностью проверенный. Образ сам доставляет Vale 3.17.0 и русский Hunspell-словарь ru-spelling-dictionary 1.0.8 с проверкой SHA-256 для amd64 и arm64. Игровой allowlist маскирует термины, но Hunspell никогда не исправляет текст автоматически. Evaluation запускается командой npx promptfoo eval -c evals/promptfooconfig.yaml; описание кейсов, baseline/candidate и дополнительных judge-метрик находится в docs/evals.md. Правила Vale, их профили и тесты описаны в docs/sidecars.md, команды диагностики стека — в docs/editor-toolchain.md.

TeamBot и Google Docs

Production gateway работает как AG-UI сотрудник TeamBot. Для ссылки Google Docs модель получает только read-only инструменты, а принятая анализатором правка регистрируется отдельным внутренним запросом:

EDITOR_OPENBOT_URL=http://openbot:3001
EDITOR_OPENBOT_TOKEN=<service token TeamBot>

Gateway передаёт TeamBot подписанный openbotRun, document ID, проверенный source и candidate. Сервисный токен не входит в model prompt или forwardedProps. TeamBot строит точные диапазоны, хранит предложение зашифрованно и возвращает только ссылку на owner-only экран diff. Документ меняется после кнопки пользователя одной revision-fenced операцией; write-tool модели не выдаётся.

Если автоматическое сопоставление небезопасно (несколько tabs, таблица, структурная правка, форматированный абзац или усечённое чтение), исправленный текст остаётся в чате без ссылки записи.

Справочник карт обновляется отдельно:

python3 .claude/skills/hs-edit/scripts/cards.py --обновить

Работа

Открыть папку в Claude Code и прислать текст. CLAUDE.md подхватывается сам.

Режим задаётся первым словом: лёгкая — только ошибки, без слова — обычная правка, глубокая — со структурой, переплавка — пересборка плохого текста по скелету жанра и манере автора, дифф — сначала список правок с причинами, рисёрч — сбор свежих данных по игре.

Проверить правку целиком:

python3 .claude/skills/hs-edit/scripts/report.py до.md после.md
python3 .claude/skills/hs-edit/scripts/soul.py после.md --было до.md

Оценки «текст стал лучше на N%» система не даёт: такой величины не существует, и любое число было бы выдуманным. Вместо неё — затронутый процент текста, изменение длины, маркеры до и после, ритм и живые сигналы.


Источники

Каталог маркеров собран из better-writing, humanizer, author-toolkit и claude-skills-journalism и переписан под русский язык: английские правила про em dash, passive voice и списки слов вроде «delve» в русском не работают, поэтому взята механика, а не словари.

Справочник карт — HearthstoneJSON, русская локализация.

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages