Учебник по Kanban
Пошаговое руководство по четырём сценариям использования, для которых разработана Kanban-система VibeOS, с открытой панелью управления в браузере. Если вы ещё не читали Обзор Kanban, начните с него — здесь предполагается, что вы знаете, что такое задача, запуск, исполнитель и диспетчер.
Настройка
vibeos kanban init # необязательно; первый `vibeos kanban <команда>` инициализирует автоматически
vibeos dashboard # открывает http://127.0.0.1:9119 в вашем браузере
# нажмите Kanban в левой навигации
Панель управления — самое удобное место для вас, чтобы наблюдать за системой. Агенты-работники, которых порождает диспетчер, никогда не видят панель управления или CLI — они управляют доской через выделенный набор инструментов kanban_* (kanban_show, kanban_list, kanban_complete, kanban_block, kanban_heartbeat, kanban_comment, kanban_create, kanban_link, kanban_unblock). Все три интерфейса — панель управления, CLI, инструменты работников — маршрутизируются через одну и ту же SQLite-базу данных на доску (~/.vibeos/kanban.db для доски по умолчанию, ~/.vibeos/kanban/boards/<slug>/kanban.db для любой созданной вами позже доски), поэтому каждая доска согласована независимо от того, с какой стороны поступило изменение.
В этом учебнике используется доска default. Если вам нужно несколько изолированных очередей (по одной на проект / репозиторий / домен), смотрите раздел Доски (мультипроект) в обзоре — те же потоки CLI / панели управления / работников применяются к каждой доске, и работники физически не могут видеть задачи на других досках.
На протяжении учебника блоки кода с пометкой bash — это команды, которые выполняете вы. Блоки кода с пометкой # вызовы инструментов работника — это то, что модель запущенного работника генерирует как вызовы инструментов — показаны здесь, чтобы вы могли видеть цикл от начала до конца, а не потому, что вы когда-либо запускали бы их сами.
Доска с первого взгляда

Шесть колонок, слева направо:
- Triage — сырые идеи. По умолчанию диспетчер автоматически запускает декомпозитор для задач здесь: встроенный декомпозитор использует
auxiliary.kanban_decomposer, читает ваш список профилей + описания и создаёт граф дочерних задач, направленных наиболее подходящим специалистам. Исходная задача остаётся активной как родительская, чтобы её исполнитель (kanban.orchestrator_profileили активный профиль по умолчанию, если он не задан) проснулся снова для оценки завершения, когда всё закончится. Переключите переключатель Оркестрация: Авто/Вручную в верхней части страницы kanban для смены режимов. В ручном режиме нажмите ⚗ Декомпозировать на карточке или выполнитеvibeos kanban decompose <id> //kanban decompose <id>. Для одиночных задач, не требующих разветвления, ✨ Специфицировать выполняет одноразовую перезапись спецификации (цель, подход, критерии приёмки) и продвигает вtodo. Настройте модели вauxiliary.kanban_decomposerиauxiliary.triage_specifierвconfig.yaml. Смотрите Авто vs ручная оркестрация в основном руководстве по Kanban. - Todo — создано, но ожидает зависимостей или ещё не назначено.
- Ready — назначено и ожидает, пока диспетчер заберёт.
- In progress — работник активно выполняет задачу. При включённых «Дорожках по профилю» (по умолчанию) эта колонка группируется по исполнителям, чтобы вы могли с первого взгляда видеть, что делает каждый работник.
- Blocked — работник запросил ввод от человека, или сработал автоматический выключатель.
- Done — завершено.
В верхней панели есть фильтры для поиска, тенанта и исполнителя, а также переключатель Дорожки по профилю и кнопка Подтолкнуть диспетчера, которая запускает один такт диспетчеризации прямо сейчас, вместо ожидания следующего интервала демона. Нажатие на любую карточку открывает её панель справа.
Плоский вид
Если дорожки профилей создают шум, отключите «Дорожки по профилю», и колонка In Progress схлопнется в единый плоский список, упорядоченный по времени захвата:

История 1 — Разработчик-одиночка выпускает функцию
Вы создаёте функцию. Классический поток: спроектировать схему, реализовать API, написать тесты. Три задачи с зависимостями родитель→потомок.
SCHEMA=$(vibeos kanban create "Спроектировать схему аутентификации" \
--assignee backend-dev --tenant auth-project --priority 2 \
--body "Спроектировать схему пользователь/сессия/токен для модуля аутентификации." \
--json | jq -r .id)
API=$(vibeos kanban create "Реализовать конечные точки API аутентификации" \
--assignee backend-dev --tenant auth-project --priority 2 \
--parent $SCHEMA \
--body "POST /register, POST /login, POST /refresh, POST /logout." \
--json | jq -r .id)
vibeos kanban create "Написать интеграционные тесты аутентификации" \
--assignee qa-dev --tenant auth-project --priority 2 \
--parent $API \
--body "Покрыть счастливый путь, неверный пароль, истёкший токен, конкурентный refresh."
Поскольку API имеет SCHEMA в качестве родителя, а tests имеет API в качестве родителя, только SCHEMA начинает в ready. Остальные две находятся в todo, пока их родители не завершатся. Это механизм продвижения по зависимостям в действии — ни один другой работник не возьмётся за написание тестов, пока нет API для тестирования.
На следующем такте диспетчера (60 с по умолчанию или немедленно, если вы нажали Подтолкнуть диспетчера) профиль backend-dev порождает работника с VIBEOS_KANBAN_TASK=$SCHEMA в его окружении. Вот как выглядит цикл вызовов инструментов работника изнутри агента:
# вызовы инструментов работника — НЕ команды, которые вы выполняете
kanban_show()
# → возвращает заголовок, тело, worker_context, родителей, предыдущие попытки, комментарии
# (работник читает worker_context, использует терминальные/файловые инструменты для проектирования схемы,
# пишет миграции, запускает свои проверки, коммитит — реальная работа происходит здесь)
kanban_heartbeat(note="схема набросана, пишу миграции сейчас")
kanban_complete(
summary="users(id, email, pw_hash), sessions(id, user_id, jti, expires_at); "
"токены обновления хранятся как sessions с type='refresh'",
metadata={
"changed_files": ["migrations/001_users.sql", "migrations/002_sessions.sql"],
"decisions": ["bcrypt для хеширования", "JWT для токенов сессий",
"7-дневный refresh, 15-минутный access"],
},
)
kanban_show по умолчанию использует task_id из $VIBEOS_KANBAN_TASK, поэтому работнику не нужно знать свой собственный id. kanban_complete записывает сводку + метаданные в текущую строку task_runs, закрывает этот запуск и переводит задачу в done — всё одним атомарным переходом через kanban_db.
Когда SCHEMA попадает в done, механизм зависимостей автоматически продвигает API в ready. Работник API, когда он подхватит задачу, вызовет kanban_show() и увидит сводку и метаданные SCHEMA, прикреплённые к родительской передаче — так он знает решения по схеме без повторного чтения длинного документа с проектированием.
Нажмите на завершённую задачу схемы на доске, и панель покажет всё:

Раздел «История запусков» внизу — ключевое дополнение. Одна попытка: результат completed, работник @backend-dev, длительность, временная метка и полная сводка передачи. Блоб метаданных (changed_files, decisions) также хранится в запуске и отображается любому последующему работнику, который читает этого родителя.
Вы можете просмотреть те же данные из своего терминала в любое время — эти команды выполняете вы, заглядывая на доску, а не работник:
vibeos kanban show $SCHEMA
vibeos kanban runs $SCHEMA
# # OUTCOME PROFILE ELAPSED STARTED
# 1 completed backend-dev 0s 2026-04-27 19:34
# → users(id, email, pw_hash), sessions(id, user_id, jti, expires_at); refresh tokens ...
История 2 — Ферма работников
У вас есть три работника (переводчик, транскрибатор, копирайтер) и куча независимых задач. Вы хотите, чтобы все три работали параллельно и показывали видимый прогресс. Это самый простой сценарий использования kanban, и именно для него была оптимизирована исходная разработка.
Создайте работу:
for lang in Испанский Французский Немецкий; do
vibeos kanban create "Перевести главную страницу на $lang" \
--assignee translator --tenant content-ops
done
for i in 1 2 3 4 5; do
vibeos kanban create "Расшифровать звонок клиента Q3 #$i" \
--assignee transcriber --tenant content-ops
done
for sku in 1001 1002 1003 1004; do
vibeos kanban create "Сгенерировать описание товара: SKU-$sku" \
--assignee copywriter --tenant content-ops
done
Запустите шлюз и отойдите — он размещает встроенный диспетчер, который подхватывает задачи всех трёх профилей специалистов в одной kanban.db:
vibeos gateway start
Теперь отфильтруйте доску по content-ops (или просто найдите «Transcribe») и вы получите это:

Две транскрибации завершены, одна выполняется, две готовы ждут следующего такта диспетчера. Колонка In Progress сгруппирована по профилю (по умолчанию «Дорожки по профилю»), так что вы видите активную задачу каждого работника без сканирования смешанного списка. Диспетчер продвинет следующую готовую задачу в выполнение, как только текущая завершится. С тремя демонами, работающими над тремя пулами исполнителей параллельно, вся очередь контента опустошается без дальнейшего вмешательства человека.
Всё, что было сказано в Истории 1 о структурированной передаче, применимо и здесь. Работник-переводчик, завершающий звонок, вызывает kanban_complete(summary="переведено 4 страницы, стиль соответствует существующему маркетинговому голосу", metadata={"duration_seconds": 720, "tokens_used": 2100}) — полезно для аналитики и для любой последующей задачи, зависящей от этой.
История 3 — Конвейер ролей с повторными попытками
Это тот случай, когда Kanban оправдывает себя по сравнению с плоским списком TODO. PM пишет спецификацию. Инженер реализует её. Рецензент отклоняет первую попытку. Инженер пробует снова с изменениями. Рецензент одобряет.
Вид панели управления, отфильтрованный по auth-project:

Цепочка из трёх этапов видна сразу: Spec: password reset flow (DONE, pm), Implement password reset flow (DONE, backend-dev), Review password reset PR (READY, reviewer). У каждого есть родитель зелёного цвета внизу и потомки в качестве зависимостей.
Интересна задача реализации, потому что она была заблокирована и повторена. Вот полная хореография трёх агентов, показанная как вызовы инструментов, которые делает модель каждого работника:
# --- Работник PM порождается на $SPEC и пишет критерии приёмки ---
# вызовы инструментов работника
kanban_show()
kanban_complete(
summary="спецификация утверждена; POST /forgot-password отправляет email, "
"GET /reset/:token отображает форму, POST /reset применяет новый пароль",
metadata={"acceptance": [
"истёкший токен возвращает 410",
"повторное использование последних 3 паролей возвращает 400 с сообщением",
"успешный сброс аннулирует все активные сессии",
]},
)
# → $SPEC завершена; $IMPL автоматически продвигается из todo в ready
# --- Работник-инженер порождается на $IMPL (первая попытка) ---
# вызовы инструментов работника
kanban_show() # читает сводку $SPEC + метаданные приёмки в worker_context
# (инженер пишет код, запускает тесты, открывает PR)
# Приходит отзыв рецензента — инженер решает, что замечания обоснованы, и блокирует
kanban_block(
reason="Рецензия: отсутствует проверка сложности пароля, ссылка сброса не "
"одноразовая (может быть воспроизведена в течение 30 мин)",
)
# → $IMPL переходит в blocked; запуск 1 закрывается с результатом 'blocked'
Теперь вы (человек или отдельный профиль рецензента) читаете причину блокировки, решаете, что направление исправления ясно, и разблокируете с помощью кнопки «Разблокировать» на панели управления — или из CLI / слеш-команды:
vibeos kanban unblock $IMPL
# или из чата: /kanban unblock $IMPL
Диспетчер продвигает $IMPL обратно в ready и на следующем такте повторно порождает работника backend-dev. Этот второй запуск — новый запуск той же задачи:
# --- Работник-инженер порождается на $IMPL (вторая попытка) ---
# вызовы инструментов работника
kanban_show()
# → worker_context теперь включает причину блокировки запуска 1, поэтому этот работник знает,
# какие две вещи исправить, вместо повторного чтения всей спецификации
# (инженер добавляет проверку zxcvbn, делает токены сброса одноразовыми, перезапускает тесты)
kanban_complete(
summary="добавлена проверка сложности zxcvbn, токены сброса теперь одноразовые "
"(хранятся + удаляются при успехе)",
metadata={
"changed_files": [
"auth/reset.py",
"auth/tests/test_reset.py",
"migrations/003_single_use_reset_tokens.sql",
],
"tests_run": 11,
"review_iteration": 2,
},
)
Нажмите на задачу реализации. Панель показывает две попытки:

- Запуск 1 —
blockedот@backend-dev. Отзыв рецензента находится прямо под результатом: «отсутствует проверка сложности пароля, ссылка сброса не одноразовая (может быть воспроизведена в течение 30 мин)». - Запуск 2 —
completedот@backend-dev. Новая сводка, новые метаданные.
Каждый запуск — это строка в task_runs со своим собственным результатом, сводкой и метаданными. История повторных попыток — это не концептуальная заплатка, наложенная поверх задачи в «последнем состоянии» — это основное представление. Когда повторяющий работник открывает задачу, build_worker_context показывает ему предыдущие попытки, так что работник второй попытки видит, почему первая попытка была заблокирована, и адресует эти конкретные замечания вместо того, чтобы начинать с нуля.
Рецензент подхватывает следующую задачу. Когда он открывает Review password reset PR, он видит:

Ссылка на родителя — это завершённая реализация. Когда работник рецензента порождается на Review password reset PR и вызывает kanban_show(), возвращаемый worker_context включает сводку + метаданные последнего завершённого запуска родителя — так рецензент читает «добавлена проверка сложности zxcvbn, токены сброса теперь одноразовые» и имеет список изменённых файлов под рукой, прежде чем смотреть diff.
История 4 — Автоматический выключатель и восстановление после сбоя
Настоящие работники терпят неудачу. Отсутствующие учётные данные, убийства OOM, временные сетевые ошибки. У диспетчера есть две линии защиты: автоматический выключатель, который автоматически блокирует после N последовательных сбоев, чтобы доска не перебиралась вечно, и обнаружение сбоев, которое возвращает задачу, чей PID работника исчез до истечения TTL.
Автоматический выключатель — постоянная на вид ошибка
Задача развёртывания, которая не может породить своего работника, потому что AWS_ACCESS_KEY_ID не установлен в окружении профиля:
vibeos kanban create "Развернуть на staging (отсутствуют учётные данные)" \
--assignee deploy-bot --tenant ops \
--max-retries 3
Диспетчер пытается породить работника. Порождение не удаётся (RuntimeError: AWS_ACCESS_KEY_ID not set). Диспетчер освобождает захват, увеличивает счётчик ошибок и пытается снова на следующем такте. Поскольку в этом примере установлен --max-retries 3, выключатель срабатывает после трёх последовательных сбоев: задача переходит в blocked с результатом gave_up. Если вы опустите флаг, VibeOS использует kanban.failure_limit (по умолчанию: 2). Больше никаких повторных попыток, пока человек не разблокирует.
Нажмите на заблокированную задачу:

Три запуска, все с одной и той же ошибкой в поле error. Первые два — spawn_failed (повторяемые), третий — gave_up (терминальный). Журнал событий выше показывает полную последовательность: created → claimed → spawn_failed → claimed → spawn_failed → claimed → gave_up.
В терминале:
vibeos kanban runs t_ef5d
# # OUTCOME PROFILE ELAPSED STARTED
# 1 spawn_failed deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
# 2 spawn_failed deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
# 3 gave_up deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
Если подключены Telegram / Discord / Slack, уведомление шлюза срабатывает на событие gave_up, так что вы узнаёте о простое, не проверяя доску.
Восстановление после сбоя — работник умирает в полёте
Иногда порождение удаётся, но процесс работника умирает позже — segfault, OOM, systemctl stop. Диспетчер опрашивает kill(pid, 0) и обнаруживает мёртвый pid; захват освобождается, задача возвращается в ready, и следующий такт отдаёт её новому работнику.
Пример в демонстрационных данных — миграция, которая исчерпала память:
# Работник захватывает, начинает сканировать 2.4M строк, OOM убивает его на ~2.3M
# Диспетчер обнаруживает мёртвый pid, освобождает захват, увеличивает счётчик попыток
# Повторная попытка с чанковой стратегией успешна
Панель показывает полную историю двух попыток:

Запуск 1 — crashed, с ошибкой OOM kill at row 2.3M (process 99999 gone). Запуск 2 — completed, с "strategy": "chunked with LIMIT + WHERE id > last_id" в его метаданных. Повторяющий работник увидел сбой запуска 1 в своём контексте и выбрал более безопасную стратегию; метаданные делают очевидным для будущего наблюдателя (или автора постмортема), что изменилось.
Структурированная передача — почему summary и metadata важны
В каждой истории выше работники вызывали kanban_complete(summary=..., metadata=...) в конце. Это не украшение — это основной канал передачи между этапами рабочего процесса.
Когда работник задачи B порождается и вызывает kanban_show(), worker_context, который он получает, включает:
- Предыдущие попытки B (предыдущие запуски: результат, сводка, ошибка, метаданные), чтобы повторяющий работник не повторял неудачный путь.
- Результаты родительских задач — для каждого родителя сводку и метаданные последнего завершённого запуска — чтобы последующие работники видели, почему и как была выполнена вышестоящая работа.
Это заменяет танец «покопаться в комментариях и выводе работы», который преследует плоские kanban-системы. PM пишет критерии приёмки в метаданных спецификации, и работник инженера видит их структурно в родительской передаче. Инженер записывает, какие тесты он запустил и сколько прошло, и работник рецензента имеет этот список под рукой, прежде чем открыть diff.
Защита от массового закрытия существует, потому что эти данные относятся к каждому запуску. vibeos kanban complete a b c --summary X (вы, из CLI) отклоняется — копирование одной и той же сводки для трёх задач почти всегда неправильно. Массовое закрытие без флагов передачи всё ещё работает для распространённого случая «я закончил кучу административных задач». Поверхность инструментов вообще не предоставляет массового варианта; kanban_complete всегда работает с одной задачей за раз по той же причине.
Просмотр текущей выполняемой задачи
Для полноты — вот панель задачи, которая ещё выполняется (реализация API из Истории 1, захвачена backend-dev, но ещё не завершена):

Статус — Running. Активный запуск появляется в разделе «История запусков» с результатом active и без ended_at. Если этот работник умрёт или истечёт по таймауту, диспетчер закроет этот запуск с соответствующим результатом и откроет новый при следующем захвате — строка попытки никогда не исчезает.
Дальнейшие шаги
- Обзор Kanban — полная модель данных, словарь событий и справочник CLI.
vibeos kanban --help— каждая подкоманда, каждый флаг.vibeos kanban watch --kinds completed,gave_up,timed_out— прямая трансляция событий терминала по всей доске.vibeos kanban notify-subscribe <task> --platform telegram --chat-id<id>` — получать пинг шлюза, когда конкретная задача завершается.