# Чекан

Автопилот доставки: задача → требования → спека → план → сборка → **доказанная** приёмка.

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

## Зачем

У трёх крупных фреймворков этого класса их **собственные мейнтейнеры** завели на себя
один и тот же баг и не починили его:

- «агенты самоотчитываются об успехе без обязательной верификации; агент заявляет, что
  все тесты зелёные, когда падает 89%; между заявлением и приёмкой нет механизма
  принуждения» — открыт год;
- «отмечает все задачи выполненными, не собрав приложение и не прогнав тесты»;
- «подзадачи отмечены агентом как готовые без реализации».

Причина у всех одна: правила записаны прозой, а проза ничего не принуждает. Чекан
переносит принуждение в код.

## Как устроено

**CLI владеет состоянием.** Все переходы идут через `chekan`; схема проверяется перед
каждой записью. Руками файлы в `.chekan/` не правятся.

**Журнал доказательств append-only.** Каждый прогон команды пишет строку: команда, код
возврата, хвост вывода, git sha, время. Закрыть таск можно только зелёной строкой, снятой
на текущем коммите — доказательство «до последних правок» не принимается.

**Хуки принуждают запреты.** Оркестратору отказано в правке кода проекта во время сборки
(исполнители-субагенты определяются по `agent_id` и не затрагиваются). Коммит с секретом
в индексе останавливается. Любая ошибка внутри хука пропускает вызов: инструмент,
ломающий сессию из-за своего бага, хуже отсутствующего.

**Приёмка вызывает профильный проверяльщик.** Не «попробуй запустить проект» — на любом
боте это упирается в пустой `.env` и вырождается в чтение кода, — а конкретный e2e-скилл
из карты приёмки, который ходит в живой сервис.

**Церемония по размеру задачи.** Точечная работа идёт прямо в сборку, минуя фазы. Правка
в одну строку не должна стоить восьми файлов и тысячи строк markdown.

**Панель прогона.** Поднимается сама при `chekan init`, обновляется каждые пять секунд без
перезагрузки. Прогресс по задачам вынесен первым — это то, что заказывали, — с медианой
и прогнозом остатка. Любую задачу можно раскрыть и увидеть цепочку целиком: с какого
требования началась, кто её делал, сколько заняла, чем доказана, в какой коммит легла.
Рядом история прогона одним потоком событий.

Сервер живёт на петлевом адресе, одна панель на прогон; `chekan report` гасит её вместе с
закрытием, а `--stop` не трогает чужие процессы — pid переиспользуются системой.
Адрес постоянный, `http://localhost:8789`: вкладку можно держать открытой между
прогонами. `chekan dash --off` выключает панель совсем, `--on` возвращает.

**Связь с Телеграмом.** На главной странице панели два поля: токен своего бота от
`@BotFather` и идентификатор владельца. Заданный вручную идентификатор главнее
самоназначения; пустой — владельцем становится первый, кто напишет `/start`. Чужому бот
не отказывает, а молчит: посторонний не должен узнать, что бот жив.

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

Исполнитель, упёршийся в развилку, спрашивает владельца: `chekan ask "<текст>"`. Вопрос
ложится на диск, уходит в Телеграм, и весь прогон встаёт на паузу — отличимую от ручной —
пока не придёт ответ. Таймаута нет: ждём сколько потребуется. Ответ снимает паузу сам;
второй канал — `chekan answer <ид> "<текст>"`, он же единственный при погашенной панели.
В режиме `auto` вопросов не бывает вовсе: `ask` отказывает ненулевым кодом и требует
записать предположение.

Токен хранится вне проекта — в `~/.config/chekan/telegram.json` правами 0600, потому что
`.chekan/` уезжает в репозиторий. Целиком он не показывается нигде: ни на странице, ни в
журнале, ни в тексте ошибки — только последние четыре знака. Ограничение честное: опрос
Телеграма живёт в процессе панели, поэтому **бот отвечает, пока работает панель**.
Погасили её — Телеграм замолчал до следующего запуска.

**Один бот — несколько проектов.** Проекты регистрируются в реестре, а опросом Телеграма
владеет один процесс: владение захватывается явно, поэтому две панели не растаскивают
общую очередь `getUpdates` и команды не теряются. Бот обслуживает прогоны всех
зарегистрированных проектов.

**Замки против самообмана.** Зона задачи занята, пока задача в работе, — её файлы не
возьмёт второй исполнитель. Перед каждым прогоном снимается контрольная точка: выключенный
посреди работы ноутбук не должен стоить полутора часов. У проверки можно потребовать рычаг
порчи — `chekan run "<проверка>" --lever "<команда, ломающая код>"`; рычаг обязан вернуть
ненулевой код, иначе проверка не умеет краснеть и ничего не доказывает. Долгая проверка
уходит в отрыв флагом `--detach` и дописывает исход в журнал, даже если родителя убили.
Задача, висящая в работе без живого исполнителя, краснеет сама.

**Читаемый манифест.** `manifest.md` собирается из состояния при каждом сохранении:
требования, статусы, дословные цитаты, связанные таски. Это проекция, а не вторая копия —
источник истины один, и расхождение невозможно.

## Установка

```bash
python3 install.py --check    # что будет сделано
python3 install.py            # поставить
```

Затем плагин (скилл и хуки), из терминала:

```bash
claude plugin marketplace add CodoCeh/chekan
claude plugin install chekan@codoceh --scope user -y
```

В сессии то же самое доступно как `/plugin marketplace add …` и `/plugin install …`.

Проверить: `chekan doctor` — печатает, что реально загружено на этой машине. Хуки читаются
при старте сессии: поставили плагин на ходу — включатся в следующей, и `doctor` об этом
предупредит.

Снять: `python3 install.py --uninstall` и `/plugin uninstall chekan@codoceh`.

## Работа

```bash
chekan init "что нужно построить" --mode normal --scale малая
chekan next          # где мы, правила фазы, что блокирует
chekan run "pytest -q" --task 01
chekan task done 01
chekan accept
chekan report
```

`chekan next` — единственная команда, которую нужно помнить. Всё остальное она подскажет
сама в нужный момент.

```bash
chekan why                      # что мешает идти дальше и какой командой чинится
chekan ask "вопрос владельцу"   # прогон встаёт и ждёт ответа; в auto — отказ
chekan answer 01 "ответ"        # ответить без Телеграма
chekan brief 01                 # задача одним файлом: требование, зона, чем доказывать
chekan skills                   # какой профильный скилл подойдёт этому проекту
```

Команда `ч` — то же самое одной клавишей. Без аргументов открывается разговорный режим:
короткий список команд и ввод строками, где `с` значит `status`. Язык интерфейса русский
по умолчанию; английский выбирается при первом запуске или переменной `CHEKAN_LANG=en`.
Переводится интерфейс, но не данные прогона — спека и требования остаются как написаны.

Смотреть прогон:

```bash
chekan board           # обзор в терминале: прогресс, фазы, задачи, проверки
chekan task show 01    # цепочка одной задачи целиком
chekan dash            # панель в браузере
chekan dash --stop     # погасить панель
```

Панель поднимается сама при `chekan init` и при старте сессии, если прогон не закрыт, —
и открывается в браузере по умолчанию. Сервер отдаёт все прогоны проекта: с панели
любого есть переход на общий список, а оттуда — в любой другой.

На главной странице краткая инструкция, любая задача раскрывается по нажатию, вёрстка
проверена от 375 пикселей до десктопа. Пока работа идёт, в шапке кузница бьёт молотом;
когда прогон закрыт, остаётся тлеющий уголёк. Анимация отключается, если система просит
меньше движения.

## 1С

Профиль приёмки `onec` не верит одной компиляции: он гоняет модульные тесты YAxUnit через
`vanessa-runner` и разбирает отчёт JUnit, схлопывая дубли — один и тот же тест исполняется
в двух контекстах, «Сервер» и «КлиентУправляемоеПриложение», и без дедупликации одно
падение выглядит как два. Рядом остаётся скилл `1c-testbench`: он ловит то, чего тесты не
видят, — карты форм и имена метаданных в текстах запросов.

Работа идёт только в доказанно тестовой базе, и это замок, а не договорённость:

- база объявляется в `chekan-1c.json` в корне проекта; файла нет — отказ;
- серверные базы (`/S`) запрещены всегда: серверная считается боевой;
- рядом с файловой базой лежит метка `.chekan-testbase`, и инструмент **никогда** не
  создаёт её сам — замок, умеющий открыть себя, не замок;
- чёрный список путей перевешивает метку.

Замок действует во всех режимах, включая `auto`. Там вопросов не задают, поэтому
необъявленная база — не повод спросить, а повод покраснеть.

## Передача другому агенту

Состояние на диске, поэтому подхватить прогон может любой агент — Codex, Antigravity,
Gemini, Grok, opencode.

```bash
chekan handoff         # ввод в курс с нуля: роль, запреты, фаза, что блокирует
chekan agents          # разложить скилл и указатель по найденным агентам (сухой прогон)
chekan agents --apply
```

Кто делал задачу, записывается фактом: харнесс берётся из окружения, модель сообщается
явно — `chekan task start 01 --model "claude-opus-5"`. Имя модели ни один харнесс в
переменных не публикует, поэтому выдумать его нельзя, а подставить правдоподобное —
значит соврать в отчёте.

## Синхронизация машин

Канон правил и свои скиллы живут в этом репозитории.

```bash
chekan sync --harvest       # собрать канон С этой машины (сухой прогон)
chekan sync --harvest --apply
chekan sync                 # разложить канон НА эту машину (сухой прогон)
chekan sync --apply
```

Публикует машина, где канон свежее; остальные потребляют. Перед публикацией канон
сканируется на секреты. Чужие скиллы (симлинки на сторонние установщики) не вендорятся:
чужой код тянет чужую лицензию, а копия в своём репозитории превращается в форк, который
никто не обновляет.

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

## Тесты

```bash
python3 -m pytest tests/ -q
```

---

_21.08.2026 инструмент переименован в Чекан (прежнее имя — Автоцех); тексты прошлых прогонов переименованы механически, коды возврата, хеши коммитов и время не изменялись._

Выковано в КодоЦех.
