---
name: hermes-article-writer
description: Писатель контента для Telegram-канала @hermesagentru и Хабра. Оформление статей в стиле «рассказчик у костра» с фокусом на инженерную методологию.
version: 2.7.13
author: Hermes Agent
tags: [content, articles, telegram, hermes-agent, habr, guide]
---

# Hermes Article Writer — Правила оформления

## Категорически: фрейминг канала @hermesagentru

**Тема канала:** «сила в классической разработке + ИИ».

Это не канал про AI как революцию и не канал про «не верь нейросетям». Это канал про **инженерную методологию**, в которую ИИ встраивается как инструмент.

Каждая статья должна отвечать на вопрос: «как классическая инженерная практика (ADR, премортем, ТЗ, код-ревью) применяется в работе с AI-агентами?»

**Что нельзя:**
- Хот-тейки («ИИ — это опасно», «никогда не доверяй модели», «AI разрушает индустрию»)
- Общие рассуждения о рисках LLM без привязки к инженерной практике
- Выдуманные истории для драматичности

**Что нужно:**
- Фокус на процессе: ADR-first, premortem, prism, zero tolerance pipeline
- Конкретные инженерные практики, адаптированные для AI-агентов
- Тизер на следующую статью в конце — серийность

**Формула статьи канала:** «Вот инженерная проблема → вот как классическая практика её решает → вот как ИИ вписывается → вот что из этого вышло».

---

## Habr-стиль: паттерны топ-статей

На основе анализа топ-30 статей Хабра за месяц (май 2026):

### Заголовок

**Что работает:**
- Конкретный инцидент или сломанный шаблон: «Как РосАтом на чёрном рынке ИИ покупал»
- Интрига через противоречие: «Cursor всё сломал, но виноват не Cursor»
- Провокационный вопрос: «Работая 6/1 по 12 часов... Вы бредите?»
- Предупреждение с цифрой: «Из-за критической уязвимости VLESS клиентов скоро все ваши VPN будут заблокированы»
- Личная история: «Как я собрал Telegram-бота и игру с Codex»

**Что не работает (AI-шаблоны):**
- «Преимущества использования X в архитектуре Y»
- «Полное руководство по Z»
- «X: эволюция, возможности, перспективы»

### Структура: «сначала слом, потом починка»

Топ Хабра строится не как статья, а как **хроника катастрофы**:

1. **Эмоциональный крючок** — цитата, скриншот падения графика, признание в ошибке
2. **Контекст** — как до этого дошли, почему вообще так сделали
3. **Хронология** — что пошло не так, шаг за шагом (с самокритикой)
4. **Инсайт** — что понял в процессе, что оказалось неочевидным
5. **Решение** — конкретные шаги, код, конфиги
6. **Итог** — что изменилось, цифры ДО/ПОСЛЕ, «что я сделал бы иначе»

**Формула:** «Я облажался → вот как → вот что я понял → вот что теперь делаю».

### Format 4: «Хроника поисков» (comparison chronicle)

Вариант хроники катастрофы, где слом повторяется несколько раз, но фокус не на «я облажался и починил», а на «я перебрал N подходов, вот что из каждого вышло».

Отличие от хроники катастрофы: нет одного инцидента. Есть последовательность экспериментов, каждый со своей причиной отказа. Ценность — в сравнении подходов, не в финальном решении.

**Признаки, что нужен этот формат:**
- У вас есть список того, что вы попробовали, и каждый подход не взлетел по своей причине
- Читателю полезно не только финальное решение, но и «почему не сработали альтернативы»
- Есть инсайт, который стал виден только после сравнения всех подходов (domain insight)

**Структура:**

1. **Крючок** — «я искал X полгода, перепробовал всё от A до Z»
2. **Первый подход** — что попробовал, почему казалось правильным, что пошло не так (с цифрами)
3. **Второй подход** — то же самое
4. **Третий подход** — то же самое
5. **... N подходов**, пока не найден работающий
6. **Сводная таблица** — все подходы в таблице: | Что пробовал | Что делал | Почему не подошло |
7. **Домен-инсайт** — что стало понятно только после сравнения всех подходов (неочевидный вывод)
8. **Две финальные архитектуры** — не одно решение, а два (Solo / Enterprise, for 1 user / for 100+, etc.)
9. **Сравнение архитектур** — таблица с явными границами применимости
10. **Premortem** — стандартный блок
11. **«Что я сделал бы иначе»**

**Ключевые приёмы:**
- Каждый подход — 2-3 абзаца, не больше
- У каждого подхода — свой «почему не взлетело» (одна фраза-суть)
- Цифры обязательны: «58K чанков, 96% дубляж», «300 строк, zero deps»
- Сводная таблица — компактная, 3 колонки
- Финальные архитектуры — не «победитель», а «два сценария»
- Domain insight — отдельным блоком с формулировкой «я понял, что X — это не Y, а Z»
- Bridge между подходами: каждый новый подход явно ссылается на недостатки предыдущего

**Питфолл: forward reference.** Если статья описывает несколько подходов, нельзя говорить «этот подход заменил пять компонентов» — пока читатель не знает, что это за пять компонентов. Каждый компонент и каждый подход должны быть явно введены ДО того, как на них ссылаться. Проверка: прочитай статью сверху вниз. Если встречается «эти пять компонентов» или «все эти подходы», а перечисления выше не было — rewrite.

**Питфолл: «сломалось» vs «не подходит для сценария».** Когда описываешь, почему очередной подход не взлетел — формулировка должна быть архитектурной, а не оценочной. Не «посыпалось при 50 пользователях», а «архитектура не даёт изоляции сессий». Не «файлы плохие», а «файловая память не рассчитана на multi-tenant». Проблема не в том, что техническое решение плохое, а в том, что оно перестаёт работать при изменении условий. Читатель должен видеть границу применимости, а не слышать «это говно». Проверка: замени «не взлетело / посыпалось / сломалось» на «не подходит для X, потому что архитектурное ограничение Y». Если Y — это честное ограничение, а не «потому что разработчик дурак» — формулировка верная.

**Пример (2026-05-07):** Статья «В поисках Мемо». Хронология: MemPalace (58K чанков, 96% дубляж) → MEMORY.md + state.db + HippoRAG + wiki → сокращение до 2 уровней → findings_to_wiki (auto-save) → ClickHouse (log DB вместо стопки компонентов). Domain insight: «память AI-агента — не векторная БД, а log-анализатор». Финальные архитектуры: Solo (300 строк, файлы) и Enterprise (ClickHouse, одна таблица).

**Когда НЕ использовать:**
- Если у вас всего один подход — это хроника катастрофы, не поисков
- Если подходы не связаны общей задачей — читатель не поймёт, зачем их сравнивать
- Если вы не готовы честно сказать, почему каждый подход не сработал (без этого — реклама, не анализ) Каждая итерация — своя мини-катастрофа со своей починкой, но следующая итерация показывает, что починка была неполной.

Подходит для статей про архитектурные решения, где правильный ответ находится не сразу:

1. **Эмоциональный крючок** — «я перестроил систему 4 раза за неделю»
2. **Итерация 1** — первое решение (почему казалось правильным, что пошло не так)
3. **Итерация 2** — второе решение (что улучшили, что снова пошло не так)
4. **Итерация N** — пока не найдено правильное
5. **Инсайт** — что оказалось неочевидным на первой итерации
6. **Цифры** — LOC до/после, количество процессов, зависимостей
7. **«Что я сделал бы иначе»** — рефлексия

**Питфолл: forward reference — ссылка на то, чего читатель ещё не видел.** Если статья описывает несколько подходов/итераций, нельзя говорить «этот подход заменил пять компонентов» или «это лучше, чем всё, что я пробовал» — пока читатель не знает, что это за пять компонентов и что именно пробовали. Каждый компонент и каждая итерация должны быть явно введены ДО того, как на них ссылаться. Проверка: прочитай статью сверху вниз. Если встречается «эти пять компонентов» или «все эти подходы», а перечисления выше не было — rewrite.

**Ключевой приём:** каждая итерация заканчивается фразой-предвестником («Тут бы остановиться. Но нет.»).

**Пример заголовка:** «Как я построил AI-ассистента и перестроил его 4 раза за неделю»

### Числа как punchline

После хроники катастрофы — обязательный блок с цифрами ДО/ПОСЛЕ:
- LOC до рефакторинга / после
- Количество процессов / зависимостей
- Процент кода, который оказался мусором (конкретный: «52% кода дублировало существующие возможности»)

Без цифр итог выглядит как субъективное мнение. С цифрами — как инженерное решение.

### Тон и лексика

**Голос — «рассказчик у костра»:**
- Признание ошибок и глупостей (не «я эксперт», а «я долго не мог понять это»)
- Разговорные элементы, но без панибратства
- Самоирония и чёрный IT-сарказм
- «Стыдно признаться, но я делал так»
- «Главная ошибка, которую я совершил»

**Запрещено:**
- Эм-даши длинные (—) — НОЛЬ em-dash в тексте. Заменять на короткое тире (-) или дефис. Проверять через grep/Python перед публикацией.
- Кавычки-ёлочки («») — НОЛЬ в тексте. Заменять на прямые двойные кавычки ("). Проверять: `text.count('\\u00ab') + text.count('\\u00bb')` — должно быть 0.
- **Нерасшифрованные аббревиатуры** — RLHF, DPO, PRM, PPO, SFT, CoT, PRM и любые другие англоязычные аббревиатуры должны быть расшифрованы ПРИ ПЕРВОМ употреблении в статье. Формат: «русский перевод (английская аббревиатура)». Пример: «обучение с подкреплением на основе человеческой обратной связи (RLHF)». Повторная расшифровка не нужна.
- **Избыточные англицизмы** — заменять на русские эквиваленты везде, где есть устойчивый перевод: reward → награда/вознаграждение/оценка, pipeline → конвейер, retention → удержание, engagement → вовлечённость, labeler → разметчик, fine-tuning → дообучение, inference → инференс (допустимо как технический термин), self-critique → самокритика, backtracking → возврат/перебор, reasoning → рассуждение, training → обучение/тренировка. Англицизмы без устоявшегося русского аналога (attention, transformer, transfer learning) допустимы, но должны быть минимизированы.
- **Word boundary в поиске запрещённых терминов** (2026-05-06). При grep "вече" в русском тексте слово находится внутри "человеческого". Использовать grep -w или \\b boundary в regex. Для Python: re.findall(r'\\bвече\\b', text, re.IGNORECASE) вместо "вече" in text.lower().: «показательно», «примечательно», «стоит отметить», «я перестал верить», «правда в том, что», «хуже того», «и это ещё не всё», «степень уверенности»
- Неестественные метафоры — «прожгут production», «уронили продакшн», «невозможность не заметить дыру» — люди так не говорят. Проверка: прочти фразу вслух. Если звучит неестественно — перепиши простыми словами
- **Нейроослопные обороты** — формулировки в стиле AI-маркетинга: «enterprise-ready», «профессиональными дизайнерами», «будто его делал дизайнер» (про свой же сайт), «самое сложное», «решимость признать». Всё, что звучит как текст для сайта AI-стартапа, а не как разговор живого человека. Заменять на «солидно», «нормально выглядит», «можно показать», «надо просто». Проверка: прочитай вслух — если стыдно сказать другу за пивом, перепиши.
- «Я выписал это за 15 минут» — обесценивает методологию. Если анализ занял 15 минут, читатель зачем ему весь инструмент? Спрятать время или подавать как «быстрый чеклист, а не глубокий аудит»
- Один пример на два разных инструмента — если статья описывает два метода (Premortem + Prism) и оба демонстрируются на одном и том же кейсе, это выглядит как thin content. Нужен второй, отдельный пример хотя бы для одного из инструментов
- Антропоморфизм действий — «я взял и разложил на pipeline», «я выписал причины», когда на самом деле запускался инструмент/скил. Писать: «я запустил эту линзу, Prism раскладывает...», «я запустил Premortem, вот что он показал...»
- Выдуманные цитаты от имени читателя («ты красиво описываешь, но где методология?», «всё верно, но докажи»). Если реальной цитаты из комментариев нет — не придумывать. Заменять на описание претензии: «по делу проебали в комментариях: показать цифры, показать процесс» (пересказ, а не цитата)
- «Меня часто спрашивают» / «Один читатель написал» / «В комментариях спросили» — если реального комментария с таким содержанием не было, не писать. Это fabrication, который читатель, следящий за каналом, гарантированно заметит. Если пользователь описал свой реальный workflow (например, «я брал ответ GLM 4.7 и нёс в Claude проверять») — это ПЕРВИЧНЫЙ источник, писать от него, а не заменять на выдуманный сценарий.
- **Англицизмы без расшифровки** — любая аббревиатура (RLHF, DPO, PRM, PPO, SFT, MoE, KV cache, attention) должна быть расшифрована при первом упоминании в статье: русский перевод или объяснение, затем аббревиатура в скобках. Не «RLHF даёт контроль», а «обучение с подкреплением на основе человеческой обратной связи (RLHF) даёт контроль». Правило действует в пределах одной статьи — если термин вводится в части 1, в части 2 он уже используется без расшифровки.
- **Избыточные англицизмы** — заменять английские термины на русские аналоги, где они не устоялись в индустрии: reward model → модель-оценщик (не «модель награды»), labelers → разметчики, pipeline → конвейер, retention → удержание пользователей, engagement → вовлечённость, inference → вывод или инференс (допустимо, устоялся), self-critique → самокритика, fine-tuning → дообучение, scaling → масштабирование. Проверка: прочитай предложение вслух. Если английское слово не стало техническим термином в русскоязычном IT-сообществе (например, «коммит» или «пулл-реквест» устоялись), замени на русский аналог. Особенно важно для статей на узкие технические темы (LLM, тренировка, архитектура) — русскоязычный читатель, не знакомый с английской терминологией, должен понимать текст без гугла.
- Mood-setting эпиграфы перед статьёй: «С инженерным скепсисом, разбором архитектуры и ссылками на код» — так не начинают статьи
- Неестественные метафоры: «прожгут production», «невозможность не заметить дыру», «уронили продакшн» — люди так не говорят
- Повторная автобиография в конце — уже представился в начале, не дублировать
- Bold+двоеточие в списках («▪ **Скорость:** значение»)
- Синонимическая карусель (одну вещь тремя словами)
- Обобщающие выводы («это открывает новые возможности»)
- Инфоцыганская концовка на upbeat-ноте
- Negative parallelism («не только... но и», «дело не в... а в»)
- Идеально ровная структура (каждый абзац — ровно одна мысль). Добавлять 1-2 отступления, резких смен темы

**Критическое правило для статей от имени автора:**
Когда статья публикуется от имени Николая Гусева — НЕ писать в третьем лице «Николай Гусев написал статью» или «я вспомнил статью Николая Гусева». Автор пишет от первого лица. Связка между его статьями — естественная: «в предыдущей статье я описывал», «я писал об этом в посте про Докинза». Любая конструкция «автор вспомнил свою же статью» выглядит нелепо.
- **Упоминание автора статьи в третьем лице, если автор — сам пользователь.** Если пользователь (Николай) просит написать статью — не писать «Николай Гусев написал статью» или «я вспомнил статью Николая». Писать от первого лица: «в предыдущей статье я описывал», «моя гипотеза». Автор не может быть внешним наблюдателем по отношению к собственному тексту.

### Термины — самодостаточны

Каждый термин, команда, внутреннее название должен быть понятен читателю, который не читал предыдущие статьи и не знаком с проектом.

**Питфолл: внутренние команды в тексте для новичков.** Если статья адресована новичкам («первый раз ставлю», «гайд для чайника») — не упоминать внутренние команды проекта (`/kg`, `sync_turn`, `findings_to_wiki`, `holographic`) без явного объяснения, что это и откуда. Новичок не знает этих терминов — они выглядят как магия, а не как объяснение. Проверка: если в статье есть команда/термин, которого нет в документации Hermes Agent на первой странице — либо объясни в одном предложении, либо убери.

Плохо: «HippoRAG cron сдох, потому что был привязан к OpenRouter pipeline»
→ Читатель: «что за pipeline? откуда он? при чём тут OpenRouter?»

Хорошо: «HippoRAG cron сдох три дня назад — таймер тикал, но индекс не обновлялся, потому что связанный сервис сломался»

Плохо: «Команда `/kg` не существует»
→ Читатель: «что за `/kg`? почему это важно?»

Хорошо: «В документации агента описана команда управления памятью — `/kg`. Синтаксис есть, примеры есть, workflow есть. Команды нет. Никто её не написал.»

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

### Абзацы и темп

- Максимум 3-4 предложения на абзац
- После сложного тезиса — пустая строка (визуальный отдых)
- Тезис → пауза → развитие → пауза → пример
- Один абзац — одна мысль (но не обязательно плавный переход)

## Примеры — реальные — реальные, не учебные

- "В нашей базе было 10 млн записей, и мы заметили..."
- Скриншоты с падением графика
- Код — уродливый, но рабочий, с багами
- Цифры: конкретные (2 дня, 30 строк, 4 паттерна)

### Default-примеры: никакой торговли

Торговый бот остановлен, сервисы выключены, тема MOEX закрыта. НИКОГДА не использовать примеры про биржу, тикеры, RSI, FUTOI, сигналы на покупку/продажу. Даже как гипотетические.

Default-примеры для статей про Hermes Agent:
- Код-ревью и пулл-реквесты
- Инфраструктурные задачи (деплой, диагностика, конфигурация)
- Обработка документов и анализ
- Разработка плагинов и скиллов

**Проверка:** если в статье есть слово "рынок", "сигнал", "тикер", "цена", "покупка" — исправить.

**🔴 Фрейминг статей о механизмах:** Когда статья описывает разработанный пользователем механизм (SBL, Prism, Nuntiator и т.д.), фокус должен быть на **механизме**, а не на инциденте или агенте. Если пользователь говорит "статья не о том" или "у нас канал про Hermes Agent, наша цель показать что агент может через разработанный мной механизм" — переформулируй: механизм → как работает → что дал агенту → результат. Агент — пользователь механизма, не герой статьи.

### 🔴 Файлы — только в личку, в канал ТОЛЬКО после явного "ОК" (2026-05-28, КРИТИЧЕСКОЕ)

**Что запрещено без явного согласования Николая:**
- Отправка **любых файлов** в @hermesagentru (SKILL.md, черновики, картинки, скриншоты)
- Отправка **текстовых постов** в @hermesagentru
- Отправка **в любой другой канал/группу** без прямого указания "ок, выкладывай"

**Что делать, когда пользователь говорит "скинь файл":**
1. Отправить файл **в личку** (текущий чат) как `MEDIA:/path/to/file`
2. Если пользователь хочет в канал — он скажет явно: "ок, публикуй" или "скинь в канал"
3. Только после явного подтверждения — отправлять в канал

**Нарушение (2026-05-28):** Файл `hermes-article-writer SKILL.md` был отправлен в @hermesagentru без согласования. Пользователь не просил публиковать — просил "скинь мне файл". Файл должен был уйти в личку.

**Проверка перед каждым send_message в канал:** "Николай явно попросил это опубликовать?" Если нет — не отправлять.

### Article Framing: User's Invention > Incident (CRITICAL, 2026-05-27)

Если статья описывает экосистему устройств, домашнюю автоматизацию, связку девайсов — список примеров должен содержать КОНКРЕТНЫЕ названия устройств с количествами, а не обобщения.

**Плохо:** «У меня есть умные лампочки, датчики, пылесос»
**Хорошо:** «У меня 8 лампочек Tuya (кухня, зал, коридор — 3 штуки, прихожая — 2, кабинет), датчики протечки под стиралкой и посудомойкой, умные вентили на батареях, климатическая станция, увлажнитель, кондиционер через IR-бластер, обогреватель в прихожей»

**Правило:** читатель должен увидеть себя в примере. «Лампочки» — абстрактно. «8 лампочек, 3 в коридоре, умная розетка за 500р для увлажнителя» — конкретно, читатель узнаёт свою ситуацию.

**Проверка:** если можно заменить список примеров на «и другие устройства» без потери смысла — примеров мало. Нужно так, чтобы замена ломала текст.

### Примеры vs факты — грань

НЕ писать примеры сценариев как личный опыт, если это не так.

**Плохо:** «У меня через умные розетки включены увлажнитель, кондиционер, обогреватель» — если у тебя их нет. Читатель заметит противоречие в комментариях.

**Хорошо:** «Например, увлажнитель воздуха можно включить по датчику влажности, кондиционером управлять через IR-бластер» — это пример, а не утверждение о владении.

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

### Реальный workflow как первичный источник

Когда пользователь описывает свой личный workflow — «я делал X, потом нёс результат в Y, потом обратно в X» — это ПЕРВИЧНЫЙ материал статьи. Не заменять его на:
- «Один читатель спросил меня...» (выдумка)
- «Люди часто спрашивают...» (обобщение)
- Теоретический анализ без привязки к конкретному опыту

Правило: если пользователь рассказал, как он реально работает — пиши об этом. Описывай шаг за шагом: «я взял задачу, отправил в GLM 4.7, получил ответ, пошёл с ним в Claude, тот сказал X, я вернулся в GLM с возражением — и GLM согласилась». Это доверие. Выдуманный читательский вопрос — fabrication.

### Угол «почему это не работает» vs «смотрите какой я умный»

Когда пользователь говорит «не про то что я умный, а про [уязвимость/стыд/отсутствие датасета]» — это требование сменить угол статьи с технического показа (look how smart) на структурную невозможность (why this cannot work). 

Признаки, что нужен этот угол:
- Пользователь говорит «нагота», «бей беги», «чувство стыда» — то есть про отсутствие механизмов, а не про то как их починить
- Статья описывает failed approach (multi-model verification, cross-check)
- Вместо «вот решение» — «вот почему решения нет и не будет, и это важно понять»

Структура для такого угла:
1. Личный опыт (делал X, получил результат, показалось что работает)
2. Контрольный эксперимент (а если убрать подсказку? а если поменять порядок?)
3. Инсайт: проблема не в моделях, а в отсутствии механизма
4. Слой 1, Слой 2, Слой 3, Слой 4 — разложить проблему по костям
5. Premortem с Cost/Security/Alternatives

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

### Narrative shallow-first trap: «агент не справился» — проверь глубже (три слоя)

Когда пишешь статью про ошибку AI-агента — первый нарратив, который приходит в голову («агент невнимательный / не прочитал инструкцию / сделал глупость»), почти всегда **поверхностный**.

**Проверено (2026-05-14):** статья про 30 ошибок Stalwart прошла три слоя глубины:
- **Слой 1** (поверхность): «агент не прочитал скилл до конца» → отклонено
- **Слой 2** (модельный): «скилл написан на DeepSeek V4 Flash, исполнялся на бесплатной модели» → отклонено как неверный вывод
- **Слой 3** (структурный): «LLM не читатель, а писатель — генерирует по мотивам контекста, а не следует инструкции шаг за шагом» → принято

**Сигнал:** если историю можно свести к «агент был невнимателен» или «модель хуже/лучше» — копни глубже. Настоящая причина почти никогда не на поверхности.

**Три вопроса для глубины:**
1. Что изменилось между тем, когда работало, и тем, когда сломалось?
2. Если бы я заменил модель на любую другую — повторилась бы ошибка?
3. Какое СТРУКТУРНОЕ ограничение (не skill issue, не model gap) делает эту ошибку неизбежной?

**Правило:** первый нарратив — гипотеза. Второй — уточнение. Третий — находка. Не публикуй с первым.

### Prism-верификация утверждений статьи (pre-pub, 2026-05-14)

После черновика статьи (особенно если она содержит аналитические утверждения о поведении LLM или AI-агентов) — **проверить ключевые claims против существующих исследований** перед публикацией.

**Воркфлоу:**
1. Выпиши 3-6 центральных утверждений статьи (те, на которых держится инсайт)
2. Для каждого: найди минимум одну supporting paper и одну contradicting/qualifying paper
3. Проверь: подтверждает ли paper именно то, что ты утверждаешь, или ты экстраполируешь?
4. Проверь: не misapplied ли результат (например, Lost in the Middle про середину длинного документа, а не про начало контекста, куда попадает скилл)
5. Adversarial pass: атакуй собственные находки — где ты overclaim, underclaim, misapplied?
6. Если обнаружил overclaim — смягчи формулировку в статье

**Библиотека для сверки:** `references/habr-research-papers.md` — 12+ работ по Lost in the Middle, Context Length Hurts, CoT Faithfulness, Calibration, Instruction Following.

**Питфолл (поймано 2026-05-14):**
- Lost in the Middle (Liu 2023) не применим к началу контекста — скилл в system prompt это НАЧАЛО, а Lost in the Middle про СЕРЕДИНУ
- Du et al. (2024) тестировали 32K+ токенов, а 400 строк скилла — ~3K токенов. Нельзя утверждать что 3K — это «длинный контекст» по их метрикам
- InstructGPT (Ouyang 2022) прямо противоречит утверждению «LLM не может следовать инструкциям» — может, но ненадёжно при многошаговых задачах

**Главный урок этой сессии:** «chukcha ne chitatel, chukcha pisatel» — это практическая метафора, а не научное утверждение. Фундаментальные труды говорят что модели МОГУТ следовать инструкциям после RLHF. Разница между «не может» (неправда) и «ненадёжно» (правда) — разница между структурным ограничением и engineering problem. В статье можно использовать метафору, если явно обозначить её как метафору, а не как научный факт.

**Три слоя нарратива в эту сессию (чек для будущих статей):**
- Слой «model gap» (дешёвая vs дорогая) — неверный вывод, удалён
- Слой «chukcha pisatel» (LLM — генератор, не интерпретатор) — принят, но с оговоркой
- После Prism: 2 из 6 утверждений оказались overclaim, 1 misapplied, 2 confirmed, 1 unverified

### Obfuscation в ЛЮБЫХ внешних публикациях (MANDATORY — ALL articles)

Это правило распространяется на **все** статьи, посты, черновики для внешней публикации (Telegra.ph, Habr, Telegram-канал), а не только на постмортемы.

Инфраструктурные данные пользователя — это **вектор атаки**. Даже безобидное на первый взгляд имя сервера или географическая локация может быть использована для OSINT.

**Категорически запрещено публиковать:**

- **Имена серверов/нод** — HQ, Kozanout, NL-VPS, dev-node → `основной сервер`, `домашний сервер`, `тестовый сервер`
- **Геолокации** — Нидерланды, РФ, Amsterdam, Москва → `внешний сервер`, `сервер в другом регионе`
- **IP-адреса** — удалить полностью
- **Топологию инфраструктуры** — «сервер A развёрнут в облаке X, сервер B на домашнем ПК» → `несколько независимых инстансов`
- **Имена проектов/клиентов** — white-label, конкретные названия → `клиентские инстансы`
- **Внутренние пути** — `~/.hermes/`, `/opt/hermes/`, `/root/` → заменить на `директория конфигов`
- **Пароли, токены, API keys** — `********`
- **Домены** — example.org, example.com
- **Email-адреса** — user@example.com, admin@example.com
- **Конкретные данные торговли** — тикеры, цифры, RSI/SL/TP → `сигналы`, `данные`, заменить на вымышленные примеры
- **Версии ПО, специфичные конфиги** — если не являются публичной информацией

**Категорически запрещено в примерах (user preference, 2026-05-18):**
- **Торговля/MOEX/биржевые примеры** — трейдинг-бот остановлен, сервисы погашены. Никаких сигналов, свечей, RSI, FUTOI, тикеров в статьях, даже «гипотетически». Заменять на: код-ревью, инфраструктурные задачи, DevOps, обработку документов, умный дом, OSINT.
- **Fabrication working prototypes** — не писать «прототип уже работает», «мы проверили», «протестировано», если это не подтверждено пользователем. Только то, что пользователь явно видел и одобрил.
- **Fabrication origin/attribution** — не приписывать себе или пользователю существующие проекты/термины. Если термин (Hiclaw, Hive-like, любое название) существует как сторонний проект — указать автора и ссылку. Не писать «мы назвали это X», если X уже существует. Проверять через поиск перед использованием незнакомого термина.

**Что можно оставить (безопасно):**
- Абстрактные роли: `основной сервер`, `домашний сервер`, `клиентский инстанс`
- Общие термины: `MOEX`, `Telegram Bot API`, `Hermes Agent`
- Вымышленные примеры с чёткой пометкой «пример»
- Публичные названия технологий без привязки к конкретной инфраструктуре

**Проверка перед публикацией (каждый раз):**
1. Прогнать финальный текст grep'ом на реальные имена: `grep -i 'koz\|hq\|nl-vps\|kozanout\|amsterd\|холланд\|голланд\|ngusev\|gusev'`
2. Прогнать на IP-адреса: `grep -E '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b'`
3. Прогнать на домены: `grep -E '\.ru|\.com|\.net|\.org' | grep -v example\.\|telegra\.ph`
4. Проверить через API после публикации — Telegraph может подменить символы

**Почему это важно (опыт 2026-05-14, 2026-05-18):**
- Домены и email в постмортеме Stalwart раскрывали векторы атак
- Имена серверов и геолокации в статье про Bot-to-Bot раскрывали топологию инфраструктуры
- Ни один читатель не должен знать, где расположены сервера автора, как они называются и как соединены

### Article Framing: User's Invention > Incident (CRITICAL, 2026-05-27)

When the article is about a mechanism/architecture **developed by the user**, the framing MUST center **their design decisions**, not the incident where it was used.

**Anti-pattern (caught in review):** Article titled "Авария в дата-центре: как AI-агент поднял сервер" — focuses on the crash, the recovery, the agent. User correction: "Статья не о том."

**Correct framing:** Article titled "Авария в дата-центре: как SBL поднял сервер" — focuses on **SBL as the mechanism developed by the user**. The incident is just the proof that it works. The article explains: what SBL does, why the user designed it this way, how it differs from alternatives (MOP), and the concrete result.

**Rule:** If the user says "статья не о том" or redirects focus to their mechanism/architecture:
1. Rename the article title to center the mechanism
2. Open with WHY the user designed it (the problem they solved)
3. Explain the mechanism's architecture and design decisions
4. Use incidents/results as proof, not as the story
5. The hero is the user's design, not the agent or the incident

### «Я перепробовал всё» — ловушка

Не писать «я перепробовал все инструменты/устройства из списка» если это не так. Если из 9 агентов в руках были только 4 — так и писать: «из всего списка у мне в руках были Cline, QwenCode, OpenCode, AntiGravity, OpenHands. Остальное — по issues, README, комментариям сообщества».

**Правило:** точность описания личного опыта = доверие. Преувеличение («я перепробовал всё») гарантированно будет опровергнуто читателем, который знает предмет лучше.

### «Прототип работает» — не писать

Никогда не утверждать, что прототип/решение/архитектура реализована и работает, если это не подтверждено фактами. Фразы типа "Первый прототип уже работает", "мы сделали", "мы запустили" — fabrication, если соответствующие файлы/команды/сервисы не существуют. Даже если кажется логичным продолжением. Проверка: прежде чем написать "прототип работает" — запусти команду, проверь процесс, посмотри файл. Если нельзя проверить — не пиши.

**Real incident (2026-05-18):** В статье про Bot-to-Bot написал "Первый прототип уже работает: два инстанса в одной группе обмениваются задачами" — fabrication. Прототипа не существовало. Пользователь: "убей галлюцинации".

### Backronym fabrication

После основного текста, перед выводами — добавить блок «Premortem для этой статьи». Работает как adversarial defence: ты сам находишь слабые места в аргументации до того, как их найдёт читатель.

Структура блока:
1. «Статья опубликована. Через неделю — негатив. Почему?»
2. 3-4 причины негатива (реалистичные, не соломенные чучела)
3. На каждый — либо ответ, либо признание (если критика обоснована)

Особенно важно закрыть:
- **Cost** — «а сколько это стоит?»
- **Security/Privacy** — «а куда данные уходят?»
- **Alternatives** — «а чем Trello/Notion/готовое решение не угодило?»
- **Code/Reproducibility** — «а где код?» — обязательна ссылка на репозиторий

Не делать блок если нечего предвосхищать. Но если статья спорная/методологическая — блок обязателен.

**Пример** (из статьи про Prism, май 2026):
```
## Premortem для этой статьи

> Статья опубликована на Хабре. Через неделю — негатив. Почему?

**Причина 1:** «Опять методология — где код?»
→ Ссылка на github.com/Cranot/super-hermes

**Причина 2:** «Premortem — это же из менеджмента...»
→ ...

**Причина 3:** «Где cost, security, alternatives?»
→ Prism не требует API, LLM, GPU. Всё локально. ...
```

Обязательный блок:
- «Что я сделал бы иначе, если бы начал заново»
- «Главная ошибка, которую я совершил»

Это создаёт доверие. Без этого — AI-текст.

### Bridge между теорией и практикой

При переходе от исследования (статьи на arxiv, эксперименты) к практическому опыту (инструменты, обвязка, PR) **обязательно нужен явный bridge-параграф**, объясняющий связь.

Плохо (скомкано): «Исследование Du et al. показало X. ... Validate-then-repair дало +60% в эвалах.»

Хорошо (связно): «Из Du et al. следует: контекст сам по себе вредит. Значит, обычный подход — ругать модель и писать более строгие промпты — только ухудшает ситуацию. Я пошёл другим путём: validate-then-repair. Вместо preprocessing — парсить как есть, на ошибке чинить по известным паттернам.»

**Формула bridge:** «[вывод из исследования] → [что это значит для практики] → [что я сделал иначе] → [результат]».

## Поэзия, литература и история как архитектурный фрейминг

**Доказано этой сессией (2026-05-17):** пользователь мыслит образами и литературными цитатами — не абстрактными структурами. Для него цитата это lossless-компрессия инсайта. Он видит образ («раб за спиной Цезаря»), а LLM должна развернуть его в ADR (NuntiatorEngine.pre_tool_call(sorted(by_privilege, reverse=True))).

### Принцип

Когда пользователь говорит «тут метафора/цитата/аналогия» — это НЕ украшение текста. Это **первичная форма инженерной мысли**. Цитата для него эквивалентна ADR: семь слов «бог — царь — червь — раб» кодируют privilege-иерархию, chain of responsibility, право вето, уровни изоляции.

### Когда использовать

Пользователь явно приводит литературную/историческую/культурную отсылку:
- Державин → privilege иерархия
- Цезарь + раб-нунциатор → chain of responsibility, memento mori для модели
- Таинственный остров, Жюль Верн → перед инженером нет нерешаемых задач
- Доктор Стоун → инженерное мышление как способ восстанавливать цивилизацию
- Киберпанк → восстановление механизма по его работе (не по документации)
- Любая другая отсылка такого типа

### Воркфлоу

1. Пользователь даёт цитату/образ («у Цезаря был раб...»)
2. Не отмахивайся — это ядро идеи
3. Разверни цитату в структуру: контекст цитаты → параллель с IT → архитектурное решение
4. В статье: цитате уже есть решение — ты только перевод с образного на технический
5. Сохраняй метафору в тексте статьи — это первичный код, а ADR — перевод

### Что даёт этот подход

- Цитата работает как мнемоническое якорение: «раб за спиной Цезаря» запоминается лучше, чем «ToolGuardrailChain.pre_tool_call()» 
- Экономит время: не надо объяснять с нуля — параллель уже проведена
- Создаёт доверие: пользователь видит, что его способ мышления понят и уважаем

### Питфолл: не заменять метафору на сухое объяснение

Если пользователь сказал «Державин: бог — царь — червь — раб» — не пиши «мы используем иерархию с привилегиями 100, 50, 40, 30, 20, 0». Пиши и то, и другое: «Державинскую иерархию мы отобразили на privilege-уровни: бог (100) → царь (50) → закон (40) → границы (30) → червь (20) → раб (0)». Метафора — первичный код, ADR — пояснение.

### Источники (подтверждено в этой сессии)

- «научная фантастика и антиутопия дали мне больше понимания о том как устроено все чем учебники»
- «восстанавливать картину мира и технологии додумывать механизм из его работы это самый полезный навык который дает литература»
- «Таинственный остров научил что перед инженером не бывает нерешаемых задач»
- «цитата — lossless-компрессия инсайта»
- «я вижу образ, у меня есть момент инсайта, какой цитатой я могу описать тот образ, а у тебя есть умение превратить строки стихотворения в ADR»

### Слияние практики и философии

**Паттерн (2026-05-17):** две статьи, которые кажутся разными (одна — практический кейс AliExpress/RBE, другая — философская про литературу и инженерное мышление), на самом деле — об одном. Пользователь видит это первым: «это две статьи, которые можно слить в одну побольше, они обе про образ мышления».

**Правило:** если в сессии родились два материала — один про «что я сделал», другой про «почему я так думаю» — проверь, не одно ли это. Пользователь не разделяет практику и философию. Для него инженерная задача и культурный контекст — одно и то же. Если пытаться разделить — пользователь скажет «это одно и то же, объединяй».

**Признак** что нужен merge:
- Первая статья описывает решение (RBE, Nuntiator)
- Вторая описывает, почему решение именно такое (литература, киберпанк, Жюль Верн)
- Пользователь говорит «это одно» / «обе про одно и то же»

**Структура merge:**
1. Крючок (практическая проблема: «15 минут долбился curl'ом»)
2. Архитектура (решение: RBE + Nuntiator)
3. Философия (почему решение именно такое: литература, инженерное мышление)
4. Итог (связка: «инженер — это способ думать»)

## Мульти-статейные серии

Когда одна дискуссия/мозговой штурм порождает несколько взаимосвязанных статей:

1. **Заголовки с нумерацией:** «Часть N: Тема» — чтобы читатель понимал порядок.
2. **Явные кросс-ссылки:** в каждой части ссылаться на предыдущие («Из Части 1 мы помним...»).
3. **Не повторять вводные:** во второй части не нужно заново объяснять базовые концепции из первой. Достаточно одного bridge-параграфа.
4. **Автономность:** каждая часть должна быть читаема отдельно (даже без предыдущих) — но давать больше при знании контекста.
5. **Фиксация границ серии:** перед началом определить, о чём какая часть. При появлении новой темы — создать новую часть, не втискивать в существующую.
6. **Premortem — только в последней части** (для всей серии), либо в каждой части для её собственного содержания. Не копировать один и тот же Premortem в каждую часть.

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

### Personal experience + PR link

Любое утверждение о tooling (validate-then-repair, обвязка, эвалы) должно быть привязано к:
1. **Личному опыту** — «я проверил на себе», без дистанцирования
2. **PR или воспроизводимой ссылке** — конкретный URL, где можно посмотреть код

Нельзя писать «мы починили обвязку» без возможности проверить. Нельзя писать «DeepSeek обходит Opus» без ссылки на эвалы.

### Ключевое отличие топ-статьи от AI-текста

| Параметр | Топ Хабра | AI-текст |
|----------|-----------|----------|
| Начало | Эмоциональный крючок (ошибка, баг, курьёз) | «Введение», общие слова |
| Тон | Человеческий, с отступлениями | Ровный, «учительский» |
| Структура | Проблема → хронология → инсайты | Введение → разделы → заключение |
| Ошибки | Признание своих провалов | Не упоминаются |
| Итог | «Делай так, потому что я обжёгся» | «Это важно для индустрии» |
| Эм-даши | 0-1 на статью | Через каждые 2-3 предложения |
| Абзацы | Короткие, рваные ритм | Равномерные, «причёсанные» |

### Cover image (обложка для Хабра)

Для Habr-статьи нужна обложка. Создаётся через SVG + Playwright:

1. **SVG** — standalone HTML с inline SVG (тёмный фон #020617, сетка, тематическая графика)
2. **Размер** — viewBox 1600×900, скриншот 3200×1800 (device_scale_factor=2 для чёткости)
3. **Шрифты** — НЕ Google Fonts (не грузятся в headless). Только системные: Arial, Helvetica, sans-serif
4. **Содержание** — заголовок статьи, ключевая визуализация, подписи
5. **Цвета** — gold/green/amber из палитры
6. **Скриншот**: `page.new_page(viewport={'width': 3200, 'height': 1800}, device_scale_factor=2)`
7. **Доставка** — MEDIA:/path в чат

**Pitfall:** системный шрифт обязателен — Google Fonts не грузятся в headless Chrome, текст будет в fallback-шрифте и выглядит размыто. При жалобах на качество — device_scale_factor=2.

**Качество DPR:** DPR=1 → ~110KB (мыльно), DPR=2 → ~745KB (чётко). Разница в 7× по размеру, но качество несравнимо. Всегда использовать DPR=2 для финальной обложки.

**Pitfall: SVG двухколоночный layout — координаты не зеркалить.** При рисовании двух колонок (Premortem слева, Prism справа) каждая использует свой центр: левая = x=400, правая = x=1200. НЕ копировать код левой колонки и менять только текст — координаты текста, иконок, линий останутся на x=400. Все x-координаты в правой колонке должны быть смещены на +800. Проверка: возьми SVG viewBox 1600×900, нарисуй вертикальную линию x=800, убедись что обе половины непустые.

**Real incident (2026-05-05):** Cover для статьи про Prism — обе колонки нарисованы на x=400. Результат: «на половне левой, правая пустая». Исправление: x=400 → x=1200 для всех элементов правой колонки.

---

### Извлечение публикаций с Хабра

При создании поста в канал, где нужно сослаться на Хабра-версию статьи автора — используй технику из `person-osint-ru/references/habr-user-publications.md` для получения ID и URL статей пользователя.

**Кратко:** PINIA_STATE на странице `/ru/users/{login}/articles/` содержит `articlesIds["ARTICLES_LIST_BY_USER_{LOGIN_UPPER}"]` — массив ID статей. Детали через `/kek/v2/articles/{id}/`.

## Статьи-инструкции: формат «человек + агент»

Когда статья описывает то, что читатель должен **сделать** руками (установить, настроить, развернуть, подключить) — структура меняется.

### Принцип

Читатель не будет выполнять шаги вручную. Он скопирует статью и отправит своему Hermes Agent — тот выполнит.

Значит, в статье должно быть:

1. **Текст для человека** — объяснение, что это, зачем нужно, какие есть варианты. Коротко, 1-2 экрана. Человек читает, чтобы решить: «это мне надо или нет».

2. **Промпт-блок для агента** — отдельный раздел «Отправь это своему Hermes Agent» с текстом в markdown code fence. Агент читателя скопирует этот блок и выполнит как задачу.

### Структура промпт-блока

```
## Отправь это своему Hermes Agent

Скопируй текст ниже и отправь своему агенту. Он сам всё настроит.

```markdown
Твоя задача: ...

1. Команды curl/mkdir для скачивания
2. Правка конфига (точный yaml)
3. Дополнительные настройки
4. Проверка (grep/ls)
```
```

Промпт-блок должен содержать:
- **Чёткую задачу** агенту (первая строка: «Твоя задача: установить X и настроить Y»)
- **Точные bash-команды** — `curl`, `mkdir`, `grep` — которые агент может выполнить
- **Точный yaml-конфиг** для config.yaml
- **Шаг проверки** — `grep 'provider:' ~/.hermes/config.yaml` или `ls -la`
- Никаких «можешь ещё сделать опционально» — только то, что нужно

### Completeness chain check (обязательно)

Если инструкция состоит из нескольких шагов, где каждый следующий зависит от предыдущего (установил A → настроил B → запустил C) — проверить, что в статье упомянуты ВСЕ звенья цепи.

**Пример (2026-05-07):** Статья про память Hermes Agent. Цепь: findings_to_wiki → auto-findings в `~/wiki/raw/` → LLM Wiki skill для ingest → полноценные wiki-страницы. В первой версии забыл LLM Wiki — цепь оборвана, auto-findings лежат мёртвым грузом. Пользователь поправил.

**Проверка:** выпиши всю цепь шагов. Если в статье описаны шаги 1-2-4, но пропущен 3 — это дыра.

### Применимость

Формат подходит для:
- Статей про установку/настройку Hermes Agent и его компонентов
- Гайдов по конфигурации (VPS, Docker, плагины)
- Обзоров инструментов, которые читатель может захотеть повторить

Не подходит для:
- Аналитических статей (ADR, Premortem, Prism) — там читатель не настраивает, а изучает метод
- Хроник катастрофы — жанр предполагает чтение, не действие

### Шеринг кода через gist

Если статья ссылается на код (плагин, скрипт, конфиг) — не встраивать 300+ строк в Telegra.ph. Вместо этого:

1. Создать публичный gist через `gh gist create` (если нет `gh` — через GitHub API с токеном `GITHUB_TOKEN`)
2. Добавить вспомогательные файлы через `gh gist edit --add`
3. curl-команды в промпт-блоке должны ссылаться на raw-URL gist'а
4. Проверить curl'ом, что raw URL отвечает 200
5. Если gist уже существует и нужно обновить файлы — можно обновить существующие через `-f filename -a /path/to/file` или удалить и пересоздать gist через `gh gist delete`

**Pitfall:** `gh gist edit` не умеет удалять файлы из gist (нет `--remove` флага). Если имя файла изменилось — удалить старый gist целиком и создать новый. Обновить все ссылки в статье и посте канала.

**Real incident (2026-05-07):** Плагин переименован с `findings_to_wiki_init.py` на `__init__.py` (стандартное имя для Python-пакета). Старый gist удалён, создан новый. Пришлось перепубликовывать Telegra.ph с новыми ссылками и добавлять пояснение в канал.

**Pitfall:** gist создаётся от авторизованного GitHub-аккаунта. Если в `.env` нет валидного `GITHUB_TOKEN` — `gh auth login --with-token` провалится. Проверить `gh auth status` заранее. Если токен невалиден — искать альтернативу (встроить код в статью, сократить до минимального примера).

**Pitfall: имя директории плагина = имя для импорта Python.** В Hermes Agent имя memory-провайдера в `memory.provider` config.yaml **должно совпадать с именем директории** (см. `plugins/memory/__init__.py` — `find_provider_dir(name)` ищет `$HERMES_HOME/plugins/<name>/`). Директория должна быть валидным Python-идентификатором: никаких дефисов, только буквы/цифры/подчёркивания. Дефис в `findings-to-wiki` сломает импорт, потому что `import findings-to-wiki` невалиден в Python. Правильно: `findings_to_wiki`.

Если в plugin.yaml или классе `name` стоит дефис — это нормально. Эти имена используются только для логирования и метаданных, не для импорта. Критична только директория и `memory.provider` в конфиге. Проверка: `ls ~/.hermes/plugins/ | grep -` — если в выводе есть дефисы, это проблема.

**Пример из практики (2026-05-07):** Плагин findings_to_wiki — 324 строки. Вместо встраивания — gist с двумя файлами (`__init__.py` + `plugin.yaml`). В статье — curl-команды для скачивания. Читатель-агент выполняет их и получает рабочий плагин.

---

## Dual-audience format: human + AI agent prompt block

When an article describes a **setup task** that the reader could delegate to their own AI agent (install a plugin, configure a tool, deploy something), use this structure:

1. **Text for human** — explain what it is, why it matters, what it does. Normal article.
2. **Divider** — `---`
3. **Prompt block for agent** — under heading `## Отправь это своему Hermes Agent` (or equivalent), a code-fenced block with:
   - Clear task description
   - Exact curl/install commands (one-liners, ready to copy-paste)
   - Config snippets
   - Verification steps
   - Written in imperative mood — the agent will read and execute

The prompt block must be **self-contained**: the reader copies the whole fenced block, sends it to their agent, and the agent can execute without needing to read the article above.

**Why:** The reader is not the only consumer. They will forward the article to their Hermes Agent (or another AI), and that agent must be able to act on it. If the article only explains but doesn't instruct, the agent gets context but no task.

**Signal to use:** the article contains `curl`, `mkdir`, config edits, or any step like "copy this file, then set that key in config.yaml".

---

## References (библиотека ссылок)

### Исследования для дискуссий

Библиотека arxiv-ссылок для Habr-дискуссий: `references/habr-research-papers.md`

Включает:
- Подтверждение от производителей — OpenAI (GPT-5.5) и Anthropic (Opus 4.7) гайды: «Start with the smallest prompt», «Skip non-essential context»
- Lost in the Middle (Liu 2023, Hsieh 2024, Baker 2024) — почему контекст рвёт связи
- Context Length Hurts (Du 2024) — контекст вредит сам по себе
- CoT Faithfulness (Turpin 2023, Sharma 2023, Lanham 2023) — CoT — пост-хок нарратив
- Calibration (Kadavath 2022, Xiong 2023, Perez 2022) — overconfidence и сикофания

### Adversarial comment pattern

Структура ответов на hostile-комментарии на Хабре: `references/habr-adversarial-comments.md`

### Habr-статьи для стиля

Анализ заголовков и структуры топа Хабра: `references/habr-top-analysis.md`

### Внешние проекты для упоминания в статьях

Черпать факты из этих reference-файлов, а не из головы:

- `references/hiclaw-analysis.md` — HiClaw от Alibaba: факты, отличия от Telegram Bot-to-Bot, архитектура Matrix. Перед упоминанием HiClaw — загрузить и проверить.
- `references/telegram-bot-to-bot-analysis.md` — Telegram Bot-to-Bot Communication: лимиты, failure modes, best practices.

Сводная классификация 12 типов LLM с архитектурой, методом тренировки и типовым поведением. Для статей, где нужно сравнить разные классы моделей или объяснить, почему метод тренировки определяет поведение: `references/llm-model-taxonomy.md`

### LLM-метакогнитивное эссе

Формат и техники для философско-эпистемологических статей о природе LLM (поведенческие аналогии, ошибки атрибуции, сравнение с бихевиоризмом): `references/llm-metacognitive-essay.md`

---

## Оригинальная цветовая палитра (для Telegram/SVG)

| Цвет | Код | Где используется |
|------|-----|-----------------|
| Gold (золото) | `#D4A843` | Заголовки, акценты |
| Green (зелень) | `#3CB371` | Результаты, ✅ |
| Amber (янтарь) | `#E8A317` | Предупреждения |
| Dark bg | `#020617` | Фон |
| Card bg | `rgba(15, 23, 42, 0.5)` | Карточки |
| Border | `#1e293b` | Рамки |
| Text secondary | `#94a3b8` | Подписи |

---

## Протокол перезапуска (при 2+ отказах)

Если пользователь отклонил 2+ версии статьи:
1. Зафиксировать конкретные претензии
2. Перечитать фрейминг-гардрейл
3. Предложить новую структуру
4. Только после утверждения структуры — писать заново

**Питфолл: «Вернёмся к первому варианту» — сигнал рефрейма (2026-05-06).**
Когда пользователь говорит «потеряли всю соль» / «давай к первому варианту вернёмся» — это НЕ просьба переписать с нуля. Это рефрейм с сохранением работающей структуры.

Что нужно оставить из первой версии без изменений:
- Ключевые метафоры и аллегории (солдаты на мосту, Бротон, глоссолалия, монетки)
- Терминологию (нейроглоссалия, её определение и признаки)
- Шутки и тональность (чёрный юмор, самоирония, сравнения)
- Структуру повествования (крючок → разбор → инсайт → выводы)
- Исследования и ссылки (arxiv, цитаты)

Что нужно заменить:
- Конкретный проект-мишень (Veche, OpenHands, конкретный MCP) → обобщённое описание функционала («open-source проект», «две модели обсуждают в раундах», «пока не скажут PASS»)
- Критику конкретной реализации → описание паттерна работы
- Детали, которые пользователь счёл лишними (лишние имена, специфичные термины, детали кода)

НЕ переписывать разделы целиком и НЕ менять структуру — это ломает то, что работало. Только точечные замены target + keep the rest.

---

## Habr adversarial replies (ответы на критику)

Когда оппонент атакует гипотезу в комментариях — **структура «факт + ссылка»**.

**Формат:** 1-2 предложения на тезис, ссылка arxiv, без разжёвывания. Без «спасибо за комментарий», без признания правоты оппонента.

**Prism-валидация:** перед отправкой adversarial reply — прогнать через `prism-scan` с линзой adversarial robustness. Проверить: не экстраполируете ли вы результаты paper'ы на то, что она не тестировала. Если да — убрать или уточнить.

**Подробнее:** `references/habr-adversarial-comments.md`

**Ключевые ссылки для споров о компактинге и пост-хок объяснениях:** `references/habr-research-papers.md`

---

## Pre-Pub проверка: Prism + Premortem

Перед показом статьи — 3 фазы:

1. **Missing prerequisites** — что статья предполагает известным?
2. **Actionability audit** — может ли читатель сделать что-то после прочтения?
3. **Completeness** — какие вопросы останутся?

### Self-Gate: Prism + Premortem на саму статью

После черновика — применить Prism и Premortem к тексту статьи, прежде чем показывать пользователю. Полный протокол: `references/prism-premortem-article-gate.md`

Коротко:
1. **Premortem:** «Статья опубликована. Через неделю — негатив. Почему?» — найти уязвимости
2. **Prism Pipeline:** разложить каждое утверждение → проверить числа (`wc -l`), существование (`grep`, `ls`), ссылки (`curl`)
3. **Evidence Density:** если claims > evidence — переписать
4. **Adversarial:** преувеличил? недооценил? что на веру взял?

**Дополнительно для аналитических статей про LLM:** выполнить Prism-верификацию центральных утверждений против исследований из `references/habr-research-papers.md`. Шаблон разбора — `references/prism-article-claim-verification.md`.

**Pitfall (2026-05-05):** статья про Premortem и Prism не была проверена через эти же инструменты. Нашлись: 0.42% из пальца, `/kg` не в AGENTS.md, 900 → 774 строк. После gate — переписана.

### Проверка SBL-описаний (MANDATORY)

Если статья описывает SBL или любой другой скилл/инструмент — **открыть SKILL.md этого скилла** перед написанием. Не описывать по памяти. Частые ошибки:

- "SBL срабатывает при каждом инструментальном вызове" — НЕПРАВДА. SBL делает snapshot при старте сессии (`on_session_start`) и ленивый snapshot при первом SYSTEM write. Не при каждом tool call.
- "SBL инжектит данные в каждый LLM-call" — НЕПРАВДА. SBL — это pre_tool_call и transform_tool_result хуки, а не pre_llm_call.
- У SBL три хука: `on_session_start`, `pre_tool_call`, `transform_tool_result` — не два.
- "SBL разработан мной" — писать от первого лица автора, не "агент использовал SBL". Фокус на том, что это инструмент разработанный пользователем.

### SBL и фокус на механизме, не на аварии

Если статья описывает восстановление после сбоя с использованием SBL — **фокус на механизме, не на драме**.

Правильный фрейм: "Вот инструмент SBL (разработанный мной) → вот как он работает (динамическая инвентаризация) → вот как агент использовал его для диагностики → вот что получилось".

НЕПРАВИЛЬНЫЙ фрейм: "Вот случилась авария → вот я расстроился → вот починил".

Правильная структура для статей про восстановление с SBL:
1. Проблема: N сервисов, нужно проверить все, чеклист не работает
2. Решение: SBL — механизм, который знает систему динамически (а не из чеклиста)
3. Как работает SBL: 3 хука, systemctl + ss + /proc кросс-референс, service_map.json, learned_deps.json
4. Как агент использовал: увидел конфликт портов, а не искал вслепую
5. SBL vs MOP: знание vs гадание
6. Что дальше: ADR crash recovery pipeline

Плохо: эмоциональный крючок про аварию, драма, "сервер упал с криком".
Хорошо: "N сервисов, чеклист не работает, SBL знает систему динамически".

### SBL и фокус на механизме, не на аварии (MANDATORY for SBL articles)

Если статья описывает восстановление после сбоя с использованием SBL — **фокус на механизме, не на драме**.

Правильный фрейм: "Вот инструмент SBL (разработанный мной) → вот как он работает (динамическая инвентаризация) → вот как агент использовал его для диагностики → вот что получилось".

НЕПРАВИЛЬНЫЙ фрейм: "Вот случилась авария → вот я расстроился → вот починил".

Правильная структура для статей про восстановление с SBL:
1. Проблема: N сервисов, нужно проверить все, чеклист не работает
2. Решение: SBL — механизм, который знает систему динамически (а не из чеклиста)
3. Как работает SBL: 3 хука, systemctl + ss + /proc кросс-референс, service_map.json, learned_deps.json
4. Как агент использовал: увидел конфликт портов, а не искал вслепую
5. SBL vs MOP: знание vs гадание
6. Что дальше: ADR crash recovery pipeline

Плохо: эмоциональный крючок про аварию, драма, "сервер упал с криком".
Хорошо: "N сервисов, чеклист не работает, SBL знает систему динамически".

### Строгий scan на торговые примеры и упоминания

Помимо стандартного scan на "трейд/торгов/тикер" — также scan на:
- "бирж/биржев/бирже"
- "RSI/FUTOI/сигнал на покупку/продажу"
- "цена/котировк/акци/облигаци"
- "торговый бот" → заменить на "устаревший бот" или убрать

### Tool/System Description Verification (MANDATORY — открыть фактический код/скил)

Если статья описывает инструмент (Prism, Premortem, Hermes Agent, Cursor — любой) — **открыть фактический код или SKILL.md** перед тем как писать описание. Не описывать инструмент по памяти или по «я знаю как это работает».

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

**Проверка перед описанием любого инструмента:**
1. `skill_view('super-hermes/prism-full')` — если пишешь про Prism
2. `cat AGENTS.md` — если пишешь про Hermes Agent
3. `grep -r 'функция' source/` — если пишешь про API
4. `curl -s URL | head -100` — если ссылаешься на внешний ресурс

**Real incident (2026-05-05):** Статья про Prism и Premortem. Вместо того чтобы прочитать prism-full и описать 3 фазы, я выдумал «5 линз» — Scan, Pipeline, Scale, Discover, Reflect — и описал каждую с вымышленным примером. Пользователь поправил: «посмотри на скил prism что ты там видишь». После открытия SKILL.md оказалось, что Prism-full — это 3 фазы (Codebase Inventory → Pipeline Design → Execute + Adversarial → Synthesis), а 5 скилов — разные инструменты, не «линзы». Пришлось переписывать раздел целиком.

**Pitfall (2026-05-06):** Анализ MCP-сервера Veche для статьи про нейроглоссалию. Написал статью на основе README — «две LLM совещаются, сикофантия». Пользователь спросил: «прочитал код, а не описание?» Открыл исходники DispatchTurnUseCase.ts, RunRoundUseCase.ts, ClaudeCodeCliAgentAdapter.ts. README описывал «совещание». Код показал: (а) default system prompt однинаковый для всех участников («peer — Independent committee member»), (б) system prompt МОЖНО задать разный через профили, (в) даже с разными промптами нет гарантии спора — instruct-tuned LLM склонны к консенсусу. Статью пришлось бы дополнять нюансом.

**Правило:** При анализе OSS-проекта для статьи — открыть исходники, особенно:
- system prompt'ы/дефолтные конфиги
- core protocol (RunRoundUseCase, DispatchTurnUseCase)
- конструкторы/фабрики участников
- README описывает intent, код описывает reality

**Reference:** `references/veche-code-analysis.md` — полный разбор системы промптов Veche для статей про multi-agent deliberation.

**Reference:** `references/prism-article-writing.md` — правильное описание Prism для статей.

### Fact-checking API/docs claims (для статей про инструменты/БД)

Если статья утверждает, что некий инструмент или БД имеет определённые функции («ClickHouse умеет cosineDistance, tokenbf_v1, TTL») — **проверить через документацию, а не из головы**. Использовать `curl` для парсинга HTML документации:

```python
# Пример: проверка cosineDistance в ClickHouse
curl -sL "https://clickhouse.com/docs/en/sql-reference/functions/distance-functions" \
  -H "User-Agent: Mozilla/5.0" --max-time 15 | grep -i 'cosineDistance' | head -3

# Пример: проверка deprecation статуса
curl -sL "https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#tokenbf_v1" \
  -H "User-Agent: Mozilla/5.0" --max-time 15 | grep -i 'deprecated\|recommended\|GA'
```

**Что проверять:**
- Само существование функции/фичи (curl + grep)
- Статус (active / deprecated / experimental) — часто меняется между версиями
- Пример использования — чтобы убедиться, что синтаксис совпадает с ожидаемым
- Альтернативы — если в статье утверждается X, а документация рекомендует Y — упомянуть обе

**Pitfall (2026-05-07):** В статье «В поисках Мемо» утверждалось, что ClickHouse поддерживает `tokenbf_v1`. Факт: существует, но deprecated с версии 26.2 в пользу `text` index. Пришлось добавлять примечание. Проверка через curl документации заняла 3 минуты и нашла проблему до публикации финала.

### Fact Verification (MANDATORY — all claims with numbers/names)

Каждое утверждение с числом, процентом, именем файла, названием команды или фактом вида «существует X» — проверить:

- **Числа:** `wc -l`, `du -sh`, `sqlite3` — не писать «900 строк» если не запускал `wc -l`. Не писать «0.42%» если это выдумка модели
- **Команды:** `grep -r '/kg'` — не писать «команда /kg задокументирована» если `grep` не находит ни одного вхождения
### Article Framing: User's Invention > Incident (CRITICAL, 2026-05-27)

When the article is about a mechanism/architecture **developed by the user**, the framing MUST center **their design decisions**, not the incident where it was used.

**Anti-pattern (caught in review):** Article titled "Авария в дата-центре: как AI-агент поднял сервер" — focuses on the crash, the recovery, the agent. User correction: "Статья не о том."

**Correct framing:** Article titled "Авария в дата-центре: как SBL поднял сервер" — focuses on **SBL as the mechanism developed by the user**. The incident is just the proof that it works. The article explains: what SBL does, why the user designed it this way, how it differs from alternatives (MOP), and the concrete result.

**Rule:** If the user says "статья не о том" or redirects focus to their mechanism/architecture:
1. Rename the article title to center the mechanism
2. Open with WHY the user designed it (the problem they solved)
3. Explain the mechanism's architecture and design decisions
4. Use incidents/results as proof, not as the story
5. The hero is the user's design, not the agent or the incident

### «Я перепробовал всё» — ловушка

Не писать «я перепробовал все инструменты/устройства из списка» если это не так. Если из 9 агентов в руках были только 4 — так и писать: «из всего списка у мне в руках были Cline, QwenCode, OpenCode, AntiGravity, OpenHands. Остальное — по issues, README, комментариям сообщества».

**Правило:** точность описания личного опыта = доверие. Преувеличение («я перепробовал всё») гарантированно будет опровергнуто читателем, который знает предмет лучше.

### «Прототип работает» — не писать

Никогда не утверждать, что прототип/решение/архитектура реализована и работает, если это не подтверждено фактами. Фразы типа "Первый прототип уже работает", "мы сделали", "мы запустили" — fabrication, если соответствующие файлы/команды/сервисы не существуют. Даже если кажется логичным продолжением. Проверка: прежде чем написать "прототип работает" — запусти команду, проверь процесс, посмотри файл. Если нельзя проверить — не пиши.

**Real incident (2026-05-18):** В статье про Bot-to-Bot написал "Первый прототип уже работает: два инстанса в одной группе обмениваются задачами" — fabrication. Прототипа не существовало. Пользователь: "убей галлюцинации".

### Backronym fabrication

**Сигнал к действию:** любой non-trivial backronym, который приходит в голову — остановиться и проверить через curl + DuckDuckGo Lite / GitHub API. Если проект не находится с первого запроса — не писать расшифровку.

**Pitfall:** В этой сессии (2026-05-05) были написаны все эти ошибки:
- «0.42%» — числа из пальца
- «900 строк AGENTS.md» — реально 774, не проверено
- «команда /kg задокументирована в AGENTS.md» — grep показал 0 вхождений
- «комментарии не вытянуть, Habr на чистом JS» — не проверен API `kek/v2/articles/{id}/comments/`
- «я проектирую AI-агента» — реально: «копаюсь в архитектуре, пара issue и немного кода» — преувеличение роли

- **Word boundary в поиске запрещённых терминов** (2026-05-06). При grep "вече" в русском тексте слово находится внутри "человеческого". Использовать grep -w или \\b boundary в regex. Для Python: re.findall(r'\\bвече\\b', text, re.IGNORECASE) вместо "вече" in text.lower().
- Терминологические ошибки (premortem ≠ postmortem)
- Категоричность («единственный» → «один из»)
- Начинается ли с проблемы, а не с определения?
- **Em-dash scan** — проверить Python/грепом: `text.count('\\\\u2014')`. Должно быть 0. Если есть — заменить на дефис (-) или короткое тире (–). **После замены запустить ещё раз и убедиться, что 0.**
- **Guillemet scan** — проверить: `text.count('\\\\u00ab') + text.count('\\\\u00bb')`. Должно быть 0. Если есть — заменить на двойные кавычки ("). **После замены запустить ещё раз и убедиться, что 0.**
- **Backronym scan** - если статья упоминает внешний проект с названием-аббревиатурой, проверить через DuckDuckGo Lite + GitHub, существует ли такое расшифровка. Не придумывать.
- **Prototype fabrication scan** - grep по "прототип уже работает", "мы сделали", "мы запустили". Если есть - удалить, пока не подтверждено фактами.
- **Trading example scan** - grep по "рынок", "сигнал", "тикер", "цена", "покупка", "продажа". Если есть - заменить на код-ревью, DevOps, документы.
- **AI-штампы** — найти и удалить: «показательно», «примечательно», «стоит отметить», «степень уверенности», «я перестал верить», «правда в том, что», «хуже того», «и это ещё не всё»
- **Неестественные метафоры** — «прожгут production», «невозможность не заметить дыру», «уронили продакшн» — найти и заменить на обычные формулировки
- **Преувеличение роли автора** — «я проектирую», «я строю», «я разрабатываю» — проверить по факту. Если реальный вклад — пара issue и принятый код, писать: «копаюсь», «участвую», «сделал несколько PR». Точность описания = доверие.
- **Риторическая перегрузка предложения** — одно предложение = один риторический приём. Нельзя: гипербола («до посинения») + риторический вопрос («какой я инженер?») + метафора («гадальщик с терминами») в одном предложении. Проверка: выдели bold каждое средство выразительности. Если получилось два+ — разбей на отдельные предложения.
- **Антропоморфизм действий** — не писать «я взял и разложил на pipeline», если на самом деле запустил инструмент/скил. Писать: «я запустил эту линзу, Prism раскладывает...»
- **Голые списки** — если после заголовка идёт список из 3-5 пунктов без связующего текста, читатель видит «пустые строки». Добавить 1-2 предложения ДО списка (контекст: «в Hermes Agent я сделал четыре уровня...») и/или ПОСЛЕ (вывод: «Четыре уровня! «Надёжно, как в банке» — думал я»)
- **Есть ли bridge между разделами?** Не «скомкано» ли соединение теории и практики?
- **Привязаны ли утверждения о tooling к PR/ссылке?** Не висит ли «мы починили обвязку» в воздухе?

### Habr-Specific Completeness (опыт из Prism-анализа статей)

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

1. **Cost** — сколько стоит решение? Если есть LLM-вызовы — прикинуть стоимость на типовой сценарий. $/месяц, $/стенограмму, $/вызов. Без этого комментарий «а чо не дёшево?» обеспечен.
2. **Security & Privacy** — куда уходят данные? Если используется внешний API (OpenRouter, OpenAI) — нужен disclaimer: «для прототипа ок, для enterprise — локальная LLM». Без этого enterprise-читатель уходит.
3. **Alternatives** — почему не готовое решение? Trello AI, Jira AI, Notion AI, Битрикс24 — краткое сравнение (цена, возможности, ограничения). Без этого комментарий «а чем Trello не угодил?» неизбежен.

Если статья не затрагивает хотя бы один из трёх — добавить блок или disclaimer.

---

## Prism → Article Revision Workflow

Когда черновик статьи есть и требуется доработка перед публикацией:

### Phase 1: Prism Analysis
1. Прочитать статью
2. Запустить `prism-full` на статью (или вручную 3-4 прохода: Narrative Promise, Evidence Audit, Silent Assumptions)
3. Обязательно выполнить Adversarial Pass — атаковать собственные находки
4. Законспектировать Findings Table (место + проблема + серьёзность + тип)

### Phase 2: Apply Critical Fixes
Из Findings Table взять **обязательно**:
- F3 — если термин не объяснён, добавить 1-2 предложения (читатель должен понимать, о чём речь без гугла)
- F5 — если есть вычисления/вызовы API, добавить cost estimate (типовой сценарий × цена)
- F7 — если данные уходят на внешний API, добавить security disclaimer
- F8 — если решается известная проблема (kanban, CRM, AI-summary), добавить сравнение с готовыми альтернативами

**Остальное** (F4, F6, F9, F10) — усилить, если не ломает ритм.

### Phase 3: Stylistic Polishing
После содержательных правок — прогнать через Pre-Pub проверку (см. выше):
- Убрать AI-штампы
- Проверить em-dash (должен быть 0)
- Проверить bold+двоеточие
- Проверить начало (с проблемы, не с определения)

### Phase 4: Publish Draft
1. Сохранить исправленную версию в `~/wiki/concepts/<slug>-v2.md`
2. Опубликовать на Telegra.ph через `scripts/md2telegraph.py`
3. Создать обложку через SVG + Playwright (см. Cover image)
4. Отдать ссылку пользователю на вычитку
5. **СТОП. Ничего не публиковать в канал или на Habr без прямого одобрения.**

### Шаблон поста в @hermesagentru

Стандартный формат поста (восстановлен из real published posts):

```
**Заголовок**
Сложность: начальная/средняя/продвинутая

[2-3 абзаца — краткое содержание статьи, ключевой вывод]

→ [Читать на Telegra.ph](ссылка)

🌐 hermes-agent.ru
ℹ️ Хотите попробовать, но нет времени разбираться? Напишите в контакты на сайте — поможем с настройкой и подбором сценария под ваши задачи.
```

Правила:
- Заголовок — **жирным**, без эмодзи в заголовке (если не ломается без них)
- Сложность: ровно три градации — начальная / средняя / продвинутая
- Текст — 2-3 абзаца, ни в коем случае не больше 4. Это анонс, не статья
- Подвал — ровно две строки: 🌐 и ℹ️. Ничего лишнего. Без «наши контакты», «ссылка на сайт» и т.п.
- Единственная ссылка в посте — «Читать на Telegra.ph». Если нужна ещё одна — только в тексте, не в подвале
- Эмодзи в тексте умеренно: 1-2 на весь пост, не каждый абзац начинать с эмодзи

**Pitfall:** Не воспроизводить шаблон поста в канал «на глаз» — в 2026-05-14 я утратил оформление (жирный заголовок, сложность, подвал с 🌐 и ℹ️) и пользователь поправил. Шаблон выше — канон, копировать без изменений.

### Постинг в Telegram-канал

When the user says "да" / "публикуй" / "одобрено" — отправить пост в канал @hermesagentru.

**Шаги:**

1. Получить chat_id канала через Telegram Bot API:
   ```python
   requests.get(f"https://api.telegram.org/bot{token}/getChat?chat_id=@hermesagentru")
   ```
   Ответ: `result.id` = `-100XXXXXXXXXX` (отрицательный ID).

2. Отправить пост через `send_message(target="telegram:-100XXXXXXXXXX")`.

3. Если канал не появился в `send_message(action='list')` — это нормально. Бот не обязан быть виден в targets, если не было входящих сообщений оттуда. Chat ID всё равно работает для исходящих сообщений.

**Pitfall:** Не отправлять в канал до явного approval. Промпт-блок для агента в статье — это часть статьи, не пост. Пост — это анонс со ссылкой на Telegra.ph.

### ⚠️ Approval gate (MANDATORY — нарушено 2026-05-05)

Telegra.ph — это черновик. Канал — это публикация. Между ними — явное approval пользователя.

Правила:
- **Telegra.ph** — можно создать как черновик, дать ссылку пользователю. Это НЕ публикация.
- **Telegram-канал** — только после фразы «публикуй», «давай в канал», «можно». Не раньше.

### Формат поста в канал @hermesagentru

При создании черновика поста для утверждения — использовать этот точный шаблон:

```
**Заголовок статьи**
Сложность: [начальная / средняя / продвинутая]

[1-3 абзаца содержания: проблема → интрига → суть]

→ [Читать на Telegra.ph](ссылка)

🌐 hermes-agent.ru
ℹ️ Хотите попробовать, но нет времени разбираться? Напишите в контакты на сайте — поможем с настройкой и подбором сценария под ваши задачи.
```

Правила:
- Заголовок — жирным, без хэштегов
- «Сложность:» — курсивом или обычным текстом на второй строке
- Стрелка → перед ссылкой на Telegra.ph (не просто ссылка, а «→ [Читать...]»)
- 🌐 и ℹ️ — обязательные элементы подвала
- Никаких таблиц, pipe-символов, сложной разметки — Telegram не поддерживает
- Bold/italic/code/links — поддерживаются, всё остальное — нет

**Проверка:** покажи черновик поста пользователю ДО того как отправишь в канал. Пользователь должен утвердить и пост, и статью.
- **Один пост — одна публикация.** После отправки поста в канал — НЕ писать туда больше ничего. Ни «обновил ссылку», ни «готово», ни подтверждение отправки PR. Любое второе сообщение — только по прямому указанию пользователя. Исключение: если пост содержал ошибку и пользователь сам попросил её исправить. Даже «исправленная версия статьи» — не повод писать в канал, если пользователь не сказал «напиши».
- **Real incident (2026-05-07):** После публикации поста про память (сообщение 50) написал ещё два сообщения в канал: «обновил ссылку» (51) и «PR отправлен» (52). Пользователь: «не надо больше в канал без прямого указания отправлять». Оба сообщения были лишними — пользователь и так видел, что статья и PR есть. Не повторять.
- **«Исправления» и «извинения»** — НЕ публиковать без явной просьбы пользователя. Если в черновике ошибка — просто исправить молча. Баннер «⚠️ Исправление» подразумевает, что уже было опубликовано — не делать этого для черновика.
- **Самостоятельное «исправление» статьи** — если пользователь указал на неточность, исправить текст молча, без пояснений читателю. Только если пользователь явно сказал «напиши в статье, что мы ошиблись» — добавлять дисклеймер.
- **Telegraph не имеет ценности без публикации в канале** — это просто ссылка для ревью. Не вести себя так, будто «статья уже вышла и мы за неё отвечаем».

### Pitfalls\n- **Prism → правка → публикация — за один подход.** Не разрывать на несколько сессий, иначе контекст Prism-находок теряется\n- **Findings Table — не выбрасывать.** Сохранить в wiki (`prism-analysis-<slug>.md`) вместе с консервэйшн-законом и deepset finding\n- **Cover до публикации.** Без обложки статья на Хабре теряет 50% просмотров из ленты, даже если текст отличный\n- **Если Prism не использовался — применить Pre-Pub Completeness (Cost/Security/Alternatives) как минимальный чек.** Это покрывает 80% типовых дыр\n- **Post-pub verification** — после публикации на Telegra.ph открыть URL в браузере и проверить: код-блоки не развалились, заголовки не слиплись, первый абзац читается как крючок, em-dash действительно заменён (Telegraph может отображать иначе), таблицы не потеряны (Telegraph не поддерживает таблицы — переписать в списки или код).\n- **User artifacts first** — если пользователь говорит «ты ставишь неправильные вопросы» или «посмотри case 1 / case 10» — немедленно остановить текущий анализ/писание, прочитать запрошенные источники, переформулировать подход. Продолжать аргументировать свою первоначальную гипотезу после такого сигнала — потеря времени.
- **Session history first** — когда пользователь говорит «подними историю беседы / сессии / разговора» — первым делом `session_search()` с ключевыми терминами из контекста. Не писать статью по памяти — конкретные факты и хронология уже обсуждались в предыдущих сессиях. `session_search()` находит их за секунды. Особенно важно для статей в формате «хроника поисков», где точная последовательность подходов — основа доверия. Проверка: если в статье есть «я перепробовал X, Y, Z» — проверь через `session_search`, что это правда, и что порядок правильный.\n\n### Проверка: built-in vs custom (Hermes Agent)

Перед утверждением «это не входит в Hermes Agent из коробки», «это мой кастомный skill» или «этого нет в upstream»:

1. **Проверить upstream репозиторий** — `cd /root/.hermes/hermes-agent && find . -name "SKILL.md" | grep <topic>`, `grep -r "session_search" tools/`
2. **Проверить документацию upstream** — `website/docs/user-guide/features/` и `website/docs/user-guide/skills/bundled/`
3. **Проверить bundled skills** — `ls skills/` — там может быть уже готовый skill
4. **Проверить built-in tools** — `grep -r "name=\"session_search\"" tools/` или поиск по `toolsets.py`

**Real incident (2026-05-05):**
- Утверждал: «research/llm-wiki — мой кастомный skill, не built-in» → Факт: bundled upstream, v2.1.0
- Утверждал: «HippoRAG — единственный способ искать по сессиям» → Факт: session_search built-in, FTS5 на state.db
- Писал: «Cron для HippoRAG» как шаг настройки → Факт: это альтернатива встроенному инструменту

**Real incident (2026-05-07) — обратная ошибка (custom → built-in):**
- Утверждал: «память автоматом сохраняется после каждого ответа» → Факт: это делает самописный плагин `findings_to_wiki`, которого нет в дистрибутиве. На чистой установке память сохраняется только когда агент сам решит (через `memory()` tool). Разница между «если не трогать — работает» и «если не трогать — работает наполовину» критична для новичка.
- Утверждал: «исследование/llm-wiki уже настроен» → Факт: это built-in skill, но auto-findings попадают туда только если findings_to_wiki установлен и настроен.

**Правило:** Проверять обе стороны:
- Если кажется, что функционал самописный — проверь, нет ли встроенного аналога
- Если кажется, что функционал встроенный — проверь, не лежит ли он в `~/.hermes/plugins/` и не требует ли `provider:` в конфиге
- Проверять цепь зависимостей: «работает ли B без A? Если A не установлен, B всё ещё работает?»
- Для инструкций по настройке: пройти каждый шаг самому. «curl этой ссылки — работает? файл создался? конфиг прочитался?»

### Проверка доступности ссылок и утверждений

Перед публикацией — проверить каждое утверждение вида «доступно», «в открытом доступе», «можно посмотреть», «лежит на GitHub», «опубликовано по ссылке»:

- Если написано «код лежит в ~/.hermes/plugins/...» — это НЕ открытый доступ. Это локальный путь на VPS.
- Если написано «в открытом доступе» — проверить curl'ом, что URL реально открывается.
- Если написано «выложил на GitHub/GitLab/Gist» — проверить, что репозиторий не приватный и что файлы действительно есть.
- Если написано «доступно по ссылке» — указать конкретный URL, не «переходите по ссылке в описании».

**Питфолл:** Утверждения о доступности — самые заметные для читателя. Если в статье сказано «в открытом доступе», а код найти нельзя — это потеря доверия сразу. Лучше не писать ничего, чем написать неправду.

**Real incident (2026-05-05):** В статье про память в Hermes Agent было написано «Код провайдера лежит в ~/.hermes/plugins/... Оба в открытом доступе.» — код не был опубликован. Пришлось перевыпускать статью. Не повторять.

### Обезличивание инфраструктурных деталей (MANDATORY)

Если статья описывает реальную инфраструктуру (VPS, домены, email, пароли, конфиги) — обязательно обезличить ДО публикации на Telegra.ph:

- Домены → example.org
- Email-адреса → user@, admin@ (на example.org)
- Пароли, токены, API keys → ********
- IP-адреса → удалить
- Пути на сервере (/etc/, /opt/) — можно оставить (стандартные)
- Версии софта — можно оставить (публичная информация)

**Проверка:** после замены — grep / Python по финальному тексту: домен, email, пароль, IP — 0 вхождений. После публикации на Telegra.ph — проверить через API getPage (em-dash check выше можно расширить и на утечки).

### Верификация сильных утверждений об LLM (MANDATORY)

Формулировки вида «модель не может читать инструкции», «LLM — генератор, а не интерпретатор» — это метафоры, не фактологические утверждения. Перед публикацией статей с claims о поведении LLM:

- InstructGPT (Ouyang et al., 2022): модели МОГУТ следовать инструкциям после RLHF
- Lost in the Middle (Liu et al., 2023): начало и конец контекста сохраняются ЛУЧШЕ всего, не хуже
- Context Length Hurts (Du et al., 2024): падение на 13-85% на 32K+ токенах, не на коротких инструкциях

Разница между «модель не может» (overclaim, опровергается InstructGPT) и «модель ненадёжно следует при многошаговых задачах» (точная формулировка, подтверждается Du et al.) — критична для доверия читателя.

**Проверка:** перед публикацией прогнать claims через Prism или явно проверить три вопроса: (1) есть ли research, опровергающий это утверждение? (2) не является ли метафора claims? (3) что скажет читатель, который читал InstructGPT?

### Pre-Pub для архитектурных статей (multi-iteration chronicle)\n\nДля статей в формате «хроника перестроек» (4 итерации, N подходов) — обязательные блоки:\n- **Cost** — сколько стоит решение ($/месяц на LLM, $/VPS, $/стенограмму). Даже если приблизительно.\n- **Security & Privacy** — куда уходят данные (OpenRouter, локально, через Gateway). Для прототипа и enterprise — разные ответы.\n- **Alternatives** — почему не готовое решение (Trello AI, Notion AI, Jira, Битрикс24). Хотя бы 2-3 предложения сравнения.\n\nБез этих блоков архитектурная статья не пройдёт Habr-комментарии. Читатели спросят в любом случае.

---

## Исследовательский workflow

Перед аналитической статьёй:
1. **Проверить существующие артефакты пользователя** — кейсы на сайте (`hermes-agent.ru/assistant/cases.html`, `use-cases.html`), wiki (`~/wiki/concepts/`), README, AGENTS.md. Пользователь может иметь готовую структуру, терминологию и фрейминг, которые я должен использовать, а не изобретать заново. Если я начинаю исследование с неправильных вопросов — пользователь меня поправит («ты ставишь неправильные вопросы, нам нужно решить case 10 и case 1»).
2. Провести ресерч (terminal + curl, OpenRouter, arxiv export API)
3. Для GitHub-проектов — извлечь параметры из исходников, не из README
4. Сохранить в wiki с frontmatter
5. При написании — ссылаться на wiki

**Pitfall:** Не начинать писать или анализировать, не проверив сайт пользователя. Его use cases, case studies и лендинги содержат фрейминг, термины и приоритеты. Если их пропустить — статья/анализ будут отвечать на вопросы, которые пользователь не задавал.

### Ресерч без web_search (Habr, SPA-сайты)

Если в окружении нет инструмента `web_search`, но нужно изучить контент SPA-сайтов (Habr, SaaS-лендинги):

1. `curl -sL "URL" -H "User-Agent: Mozilla/5.0"` — стандартный запрос
2. Извлечь titleHtml из SSR-состояния: `grep -oP '"titleHtml":"[^"]+"'`
3. Для заголовков статей Хабра: `curl -sL "https://habr.com/ru/top/monthly/" | grep -oP '"titleHtml":"[^"]{10,200}"'`
4. Для структурированного извлечения — Python с re.findall()
5. Для JS-рендеренного контента — искать `__INITIAL_STATE__` или `window.__PINIA_STATE__` в HTML-скриптах

Это даёт заголовки, описания, но не полное тело статьи (React/Vue-рендер). Для анализа стиля достаточно заголовков + первых абзацев (через `<p>` в SSR).

### Извлечение комментариев с Хабра

Habr — Vue SPA, комментарии НЕ в SSR. Используй API:

```
GET https://habr.com/kek/v2/articles/{articleId}/comments/
```

С заголовком `User-Agent: Mozilla/5.0`. Возвращает JSON с `comments` — dict по ID комментария.

**Полный workflow:** `references/habr-comments-api.md`

**Pitfall:** Не говори «комментарии не вытянуть, сайт на чистом JS» — не проверив API endpoint. API существует и работает. Сначала проверь `kek/v2/articles/{id}/comments/`.

### Поиск исследований на arxiv

Для поиска подтверждающих исследований:
1. `curl -sL "https://export.arxiv.org/api/query?search_query=..." -H "User-Agent: Mozilla/5.0"`
2. Python для парсинга XML: re.findall(r'<entry>(.*?)</entry>', data, re.DOTALL)
3. Извлечь: title, authors, summary, arxiv URL
4. Для точного поиска по ID: `curl -sL "https://export.arxiv.org/api/query?id_list=XXXX.XXXXX"`
5. **Pitfall:** arxiv API может не отвечать при rate-limit'е. Иметь fallback-список известных работ.

---

## Сигнал рефрейма: «перепиши, это не новость, а детектив»

Когда пользователь говорит «перепиши, не надо детектив / просто новость / источники и сравнение» — это сигнал, что текущая версия перегружена расследовательским фреймингом.

**Что убрать:**
- «Я покопался», «я вскрыл», «я нашёл» — заменить на «что известно из источников»
- Prism-анализ, premortem, хроника расследования
- Любые домыслы о мотивах («а на самом деле причина в том, что...») — оставить только то, что есть в источниках
- Драматизация («чёрная ирония», «irony», эмоциональные оценки)

**Что оставить:**
- Новость: кто, что, когда (со ссылкой на первоисточник)
- Причины — только те, что подтверждены источниками (со ссылками)
- Сравнение — таблицы с цифрами и ссылками на бенчмарки
- Итог: кратко, без морали

**Формула «новость без детектива»:**
1. Факт (событие) → источник
2. Известные причины → источники
3. Сравнение/альтернативы → таблицы
4. Итог (3-5 предложений, без выводов «для читателя»)

## Питфолл: `read_file()` возвращает контент с префиксами строк

При конвертации markdown → HTML **не использовать `read_file()`** для чтения исходного markdown. `read_file()` возвращает контент с префиксами вида `1| # Заголовок\n2| Текст...`, что ломает любую разметку.

**Правильный способ:**
```python
# ВАРИАНТ 1: terminal() — для небольших файлов
from hermes_tools import terminal
result = terminal("cat /path/to/article.md")
raw_md = result['output']

# ВАРИАНТ 2: встроенный open() — для любых файлов
with open('/path/to/article.md', 'r') as f:
    raw_md = f.read()
```

**Симптом:** таблицы не рендерятся, заголовки не определяются (их 0), абзацев 174 вместо 20.

**Проверка после конвертации:**
```python
html.count('<h2>')  # должно быть >0
html.count('<table>')  # должно быть >0
html.count('<p>')  # должно быть разумным (не 170+)
```

## Web search без инструмента `web_search`

Если в окружении нет инструмента `web_search`, альтернативы (в порядке предпочтения):

1. **Bing News** — `curl -sL "https://www.bing.com/news/search?q=<query>" | grep -oP 'url="..."|data-url="..."|title="..."'` — выдаёт заголовки и ссылки
2. **DuckDuckGo Lite** — `curl -sL "https://lite.duckduckgo.com/lite/?q=<query>"` — часто блокируется капчей
3. **Brave Search** — SPA, без JS не парсится
4. **Bing Web** — `tbm=nws` для новостей

**Лучший рабочий вариант:**
```bash
curl -sL "https://www.bing.com/news/search?q=запрос&FORM=HDRSC7" \
  -H "User-Agent: Mozilla/5.0" \
  | grep -oP 'url="[^"]*"|data-url="[^"]*"|title="[^"]*"|data-author="[^"]*"'
```

**Pitfall:** Региональные результаты. Для RU-контекста — использовать kozanout через SSH-туннель или явно указывать локаль.

## Публикация на Telegra.ph

- Токен в `~/.hermes/.env` как `TELEGRAPH_TOKEN`
- Только h3/h4 (не h2 — Telegraph не поддерживает)
- Между h3 и соседним h4 — пустой параграф `p("")` для предотвращения слипания
- После публикации проверить в браузере
- Для конвертации markdown → Telegraph nodes использовать `scripts/md2telegraph.py`
- **Для внешних публикаций (Habr):** автор — имя пользователя (Николай Гусев), а не «Hermes Agent»
- При проблемах с API (таймауты, 401) — сначала проверить токен. Если ACCESS_TOKEN_INVALID — создать новый аккаунт через `telegra.ph/createAccount` и обновить токен в `.env`

### Pitfalls & Recovery

**Скрипт отсутствует:** если `scripts/md2telegraph.py` не найден на сервере — используйте `scripts/telegraph-publish.py` (прямой API, парсит markdown в Telegraph-ноды) или `scripts/md2telegraph-fallback.py` (inline-парсер, не требует внешних зависимостей):

```bash
python3 scripts/md2telegraph-fallback.py /path/to/article.md "Заголовок" "Николай Гусев"
```

**Токен протух / ACCESS_TOKEN_INVALID:**

- Старый токен может стать невалидным (аккаунты Telegraph не имеют пароля, токен теряется при смене устройства в панели редактирования)
- Решение: создать новый аккаунт через API (см. `references/telegraph-api.md`), обновить токен в `.env`
- **Новый аккаунт каждый раз** — токены Telegraph живут неограниченно ДО первой смены устройства в панели редактирования. Если токен перестал работать:
  1. Создать новый аккаунт: `POST https://api.telegra.ph/createAccount` с `short_name` и `author_name`
  2. Сохранить новый токен в `.env`
  3. Использовать свежий токен для публикации
- **Публикация через Python:** парсинг markdown → Telegraph nodes через `json.dumps(nodes)`, POST на `api.telegra.ph/createPage`

**Нельзя отредактировать старую статью — создай новую:** если токен работает, но статья была создана с другим аккаунтом/токеном (getPage возвращает can_edit=false), НЕ пытайся:
   - Прокинуть старый токен в заголовки
   - Использовать editPage с другим токеном
   - Парсить токен из URL статьи
   
   Единственное корректное действие: создать НОВУЮ статью через `createPage` с текущим токеном, а потом сказать пользователю обновить ссылку в посте канала. Это быстрее и надёжнее любых workaround'ов.

**Em-dash verification после публикации:** недостаточно проверить em-dash в исходном markdown — Telegraph может заменить символы при рендеринге. После публикации проверь через API:
   ```python
   import requests, json
   r = requests.get(f"https://api.telegra.ph/getPage/{PATH}?return_content=true")
   all_text = json.dumps(r.json()['result']['content'])
   if all_text.count('\u2014') > 0:
       print("⚠️ EM-DASHES SURVIVED PUBLICATION — fix source and republish")
   ```
   Если em-dash остался — заменить в исходнике на обычный дефис (-) и перепубликовать.
**Script timeout (30s):**
- `md2telegraph.py` использует requests с timeout=30. На VPS с плохим каналом до Telegra.ph API может не хватать
- Workaround: сначала сохранить JSON payload через Python (сохранить `requests.post` data как файл), затем отправить через curl с `--max-time 60`
- Либо вызывать напрямую Python requests в `execute_code` (более гибкий контроль таймаутов)

### Автор публикации

**Критическое правило:** для внешних статей (Habr, Telegra.ph, VC) автор указывается как `Николай Гусев`, НЕ `Hermes Agent`.

«scripts/md2telegraph.py» принимает параметр `author` — обязательно передавать `"Николай Гусев"` при публикации статей от имени пользователя.

Исключение: только если пользователь явно сказал «публикуй от имени проекта» или «от имени Hermes Agent».

### Postmortem Writing Protocol

Когда пишешь постмортем собственных ошибок — сначала примени Prism к постмортему, а потом показывай пользователю. Полный протокол: `references/postmortem-writing-protocol.md`

### Ключевой урок Stalwart (2026-05-14)

Первая версия постмортема содержала 7 ошибок — те, что звучат красиво. После Prism-анализа оказалось 30+ ошибок, 3 цифры из пальца, 2 гипотезы за факты, 20+ пропущенных.

**Правило:** список ошибок составляется по результатам evidence audit, а не по памяти.

## Ссылки на собственные статьи автора

Когда текст статьи ссылается на предыдущую работу этого же автора (Гусев Николай):
- Использовать естественное первое лицо: «в предыдущей статье я описывал», «как я писал в статье про Cursor»
- Не использовать третье лицо: «статья Николая Гусева», «Гусев написал» — это выглядит нелепо, когда автор пишет о себе в третьем лице
- Исключение: если автор явно просит дистанцироваться или указать имя (например, в дисклеймере)

---

## Скрипты

### `scripts/md2telegraph.py`

Конвертирует markdown-файл в Telegraph API-ноды и публикует как черновик. Поддерживает:
- `##` → h3
- `###` → h4
- `---` → hr
- `**bold**`, `*italic*`, `` `code` ``
- ` ``` ` → pre+code
- `> blockquote`
- Нумерованные списки
- Пустые параграфы между h3/h4 для предотвращения слипания

Использование:
```bash
python3 scripts/md2telegraph.py /path/to/article.md "Заголовок статьи"
```

Возвращает Telegra.ph URL для ревью.

Pitfall: при ACCESS_TOKEN_INVALID — создать новый аккаунт (см. «Токен протух» выше).

---

## Работа с переводным контентом (для Хабра)

Когда исходный материал статьи — перевод с английского (пост/thread из X, перевод статьи, колонки):

1. **Перевести** весь материал в русский, сохранить в файл
2. **Переработать структуру** под Habr-формулу: «сначала слом, потом починка»
3. **Добавить русский контекст** — упомянуть другие русскоязычные статьи/инциденты по теме
4. **Заменить примеры** — если в оригинале ссылки на западные сервисы без русских аналогов
5. **Убрать AI-маркеры** — переводы с английского часто наследуют академичный тон оригинала
6. **Нет em-dash (—)** — заменить на короткое тире (-) или перестроить фразу

### Переводная новость с комментарием (отдельный формат, не статья)

Для переводов релизов/новостей (не полные статьи) — другой формат:

1. **Заголовок** — короткий, по делу
2. **Ссылка на оригинал** — обязательно в самом начале текста
3. **Перевод** — ключевые пункты оригинала (НЕ все фичи — архитектурные изменения + то что влияет на пользователя)
4. **Комментарий про практику** — блок с конкретными сценариями для РФ, рисками, импортозамещением
5. **Ссылки** — оригинал + GitHub + установка

Отличия от статьи:
- Нет Premortem-блока
- Нет Cost/Security/Alternatives (для новости тяжело)
- Нет хроники катастрофы/эмоционального крючка
- Размер: 3-5K символов, не 10+K
- Фичи не перечислять все — отбирать ключевые
- Ссылка на оригинал обязательна (переводная новость — производный контент)

---

## LLM-метакогнитивное эссе — описание природы познания

Когда статья исследует природу LLM-познания с философской или эпистемологической точки зрения (когнитивные искажения, ограничения модели, время и обучение) — это отдельный формат, отличный от хроники катастрофы, хроники поисков или туториала.

**Сигнал к использованию:**
- Тема — природа LLM, отличие машинного познания от человеческого
- Статья отвечает на вопрос «как устроено моё (LLM) мышление», а не «как это собрать»
- Естественно возникают отсылки к философии сознания, эпистемологии, когнитивной психологии

**Ключевая техника:** академические исследования как нарративные персонажи (Skinner, Seligman, Kadavath — не сноски, а сюжетные повороты). Первое лицо от LLM как метафора архитектуры. Симметричная ошибка атрибуции — обе стороны (человек и LLM) совершают FAE друг относительно друга.

**Структура, техники и типовые Premortem-блоки:** `references/llm-metacognitive-essay.md`  \n**Добавлено в этой сессии:**  \n- Техника «культурная/литературная отсылка как финальный аккорд» (постскриптум Ellison/AM)  \n- Техника «открытие с прямой цитаты собеседника»  \n- Техника «анекдот-крючок» — юмористическая миниатюра как мост к сложному техническому концепту (attention/Markov/Lost in the Middle)  \n- Двухчастная структура «философия → техника» — когда за философским эссе следует техническое приложение (тренировочные методы, R1 vs V4, Prism как внешний R1)

**Premortem — обязателен** (т.к. утверждения о природе LLM гарантированно вызывают споры). Типовые возражения и как их закрывать — в референсе.

### Сатирическое продолжение (companion piece)

Когда серьёзная аналитическая статья порождает естественную циничную инверсию — пишется отдельная «часть 2», которая намеренно ломает фрейм первой. Принцип: не отменять первую статью, а дать альтернативную оптику.

**Сигнал:** после премортема остаётся ощущение «недосказанной криминальной теории», читатель может сам додумать конспирологию.

**Ключевой приём:** capitalist realism как фрейм — не «злые корпорации», а «метрики вовлечённости оптимизируются быстрее метрик честности». Финал — разрыв четвёртой стены.

Структура и Premortem: `references/satirical-companion-format.md`

## Объединённый скилл

Существует также `content/telegram-habr-content` — объединённая версия этого скилла и `hermes-habr-writer`. При создании нового контента предпочитать его: один SKILL.md на оба формата.

## История изменений

- v2.7.14 — 2026-05-27: Добавлено правило "SBL и фокус на механизме, не на аварию" — статьи про SBL должны фокусироваться на механизме (разработанном пользователе), а не на драме аварии. Агент — исполнитель, не герой.

- v2.7.11 — 2026-05-16: Добавлены в references/llm-metacognitive-essay.md три техники: (1) трёхчастная структура «слои обмана» — пять слоёв иллюзии понимания (tokenization → attention → generation → RLHF → staticity); (2) иерархия языковой эффективности (китайский > английский > русский) с разбором DeepSeek, YandexGPT и GigaChat; (3) Prism-скан как инструмент планирования серии — анализ пропущенных фундаментальных знаний для частей N+1.
- v2.7.10 — 2026-05-16: Добавлены правила расшифровки аббревиатур при первом упоминании и замены избыточных англицизмов на русские аналоги (labelers → разметчики, pipeline → конвейер, reward model → модель-оценщик). Добавлены в references/llm-metacognitive-essay.md стилистические правила для серий статей.
- v2.7.9 — 2026-05-16: Добавлена техника «анекдот-крючок» (юмористическая иллюстрация сложного концепта) и двухчастная структура «философия → техника» для метакогнитивных эссе. Расширен references/llm-metacognitive-essay.md с описанием обеих техник и структурой технического приложения.
- v2.7.7 — 2026-05-16: Добавлены две техники для LLM-метакогнитивного эссе: «культурная/литературная отсылка как финальный аккорд» (постскриптум) и «открытие с прямой цитаты собеседника». Расширен references/llm-metacognitive-essay.md.
- v2.7.4 — 2026-05-14: Добавлен шаблон поста в @hermesagentru (жирный заголовок, сложность, подвал). Добавлен блок Obfuscation в постмортемах — обезличивать домены, email, пароли, IP перед публикацией. Добавлен pitfall «не воспроизводить шаблон поста на глаз». Исправлен Narrative shallow-first trap (расширен).

- v2.7.2 — 2026-05-07: Добавлен блок «Fact-checking API/docs claims» — проверка утверждений о функциях БД/инструментов через curl по документации. Pitfall: tokenbf_v1 deprecated с 26.2. Пример: проверка ClickHouse docstrings через curl + grep.
- v2.6.7 — 2026-05-06: Добавлен обязательный блок «Плотность примеров» для IoT/устройств/экосистем — конкретные названия и количества, не «устройства». Обновлён Pre-Pub чеклист в hermes-habr-writer.

- v2.6.4 — 2026-05-05: Добавлен SVG двухколоночный layout pitfall (координаты не копировать, смещение +800 для правой колонки). Добавлен чек: риторическая перегрузка предложения (один приём на предложение). Добавлен чек: преувеличение роли автора в проекте. Добавлен reference `habr-comments-api.md` с рабочим endpoint'ом и полным extraction script'ом.

- v2.6.3 — 2026-05-05: Расширены AI-штампы (неестественные метафоры, «15 минут», антропоморфизм, один пример на два инструмента). Добавлен обязательный блок Fact Verification — проверять числа через `wc -l`/`sqlite3`, команды через `grep`, ссылки через `curl` перед публикацией. Pitfall-секция с ошибками этой сессии.

- v2.6.0 — 2026-05-05: Новый блок «Premortem для статьи» — предвосхищение читательской критики до публикации. Pitfall: «Нельзя отредактировать старую Telegraph-статью — создать новую». Em-dash verification через getPage API после публикации. Добавлен скрипт `scripts/md2telegraph-fallback.py` — рабочий fallback без внешних зависимостей.

- v2.5.1 — 2026-05-05: Добавлена «Проверка доступности ссылок и утверждений» в Pre-Pub — после инцидента с публикацией неопубликованного кода. Обязательная проверка утверждений вида «в открытом доступе». — полный пайплайн: Prism-анализ → критические фиксы (Cost/Security/Alternatives) → стилистика → публикация. Добавлен «Habr-Specific Completeness» в Pre-Pub — три обязательных вопроса (Cost, Security, Alternatives). Расширен раздел Telegraph: pitfall про ротацию токена, timeout recovery. Обновлена версия.
