Beans и задачи
TR
На этой странице
Эта страница сгенерирована из content/docs/beans-and-todos/ — каждый раздел ниже ссылается на собственный исходный файл.
✎ Edit TR
Beans предназначены для агентов. Задачи (todos) — для людей. В обычной речи они обозначаются одним и тем же словом, но больше ничего общего между ними нет, и их смешение приводит к тому, что в плане работы оказываются две разные категории вещей, требующие совершенно разного обращения.
Bean — это состояние процесса, которое агент ведет во время работы:
он резервируется (claim) перед началом, чтобы соседняя сессия его не брала,
поддерживается в актуальном состоянии по ходу выполнения и закрывается
с фиксацией того, что изменилось. Хранилище — директория beans/, зафиксированная в git,
поэтому оно сохраняется при удалении или пересоздании контейнера и доступно любой другой сессии.
Todo (задача человека) — это личное напоминание: то, на что человек собирается обратить внимание в следующий раз. Только он сам решает, когда её создать, переставить или удалить, исключительно по собственному графику, и никакой процесс агента не должен определять, когда она выполнена.
На этой странице подробно описано первое. Второе пока еще не реализовано, о чем здесь прямо сказано.
Две вещи с одним названием
✎ Edit TR
Различие здесь не терминологическое. У них разные владельцы, разные жизненные циклы и разные сценарии сбоев.
| Bean | Todo | |
|---|---|---|
| Владелец | Сессия агента | Человек |
| Назначение | Состояние процесса для текущей работы | Напоминание о намерении |
| Хранилище | beans/, зафиксировано в git и общедоступно | Пока не определено |
| Создается | Агентом, после проверки точного совпадения заголовка | Человеком, в любой удобный момент |
| Закрывается | Агентом, выполнившим работу, с описанием изменений | Человеком, по собственному усмотрению |
| Доступность | Каждой соседней сессии | Прежде всего самому человеку |
| Сценарий сбоя | Дублирование или закрытие не той сессией | Забывание |
Именно сценарии сбоев делают это разделение принципиально важным. Дублирование bean лишает план работы полезного сигнала — в одном фолио неосторожный повторный запуск породил 14 688 дубликатов, то есть 92 % всех открытых beans в репозитории. Забытая задача todo доставляет неудобство только одному человеку. Механизмы, спроектированные для первого случая, оказываются излишней бюрократией для второго, а механизмов, рассчитанных на второй случай, катастрофически недостаточно для первого.
Жизненный цикл агентского bean
✎ Edit TR
Приведенная выше диаграмма описывает весь цикл, и три ее перехода заслуживают того, чтобы перечитать их дважды.
Первый шаг — это поиск, а не создание. Команда beans create
не идемпотентна: при каждом вызове она генерирует новый идентификатор и не
выполняет дедупликацию, поэтому повторный вход в шаг рабочего процесса
дублирует план вместо того, чтобы ничего не делать. Проверка по точному совпадению
заголовка — это то, что стоит между повторным шагом процесса и появлением
множества почти одинаковых beans.
Владение — это шлюз, а не вежливость. Bean, зарезервированный другой сессией, не вам разрешать, списывать или удалять. Резервирование позволяет двум сессиям не брать одну и ту же задачу; закрытие чужого bean приводит к тому, что сессия теряет результаты работы, о которых еще не успела сообщить.
«Заблокировано» — это не «ненужно». Заблокированный bean возвращается
в статус todo с зафиксированным блокирующим фактором и указанием того, что помогло
бы его устранить. Оставить его со статусом in-progress хуже обоих вариантов:
пункт, по которому никто не ведет работу, воспринимается всеми остальными
сессиями как активная задача.
Bean никогда не удаляется
✎ Edit TR
Команда beans delete есть в CLI. Не используйте ее.
Работа, оказавшаяся ненужной, списывается (scrapped) — со статусом status: scrapped
и разделом, поясняющим причину. Именно это здесь означает «отключить» (disable); в CLI
нет состояния disabled, а его словарь статусов включает draft, todo,
in-progress, completed, scrapped.
Причина не в педантичности. Списанный bean фиксирует, что нечто было рассмотрено и отклонено, и на каких именно основаниях — что столь же ценно для следующего агента, как и запись о выполненной работе, потому что именно это не позволяет снова зайти в тот же тупик. Удаленный bean оставляет соседнюю сессию в неведении, был ли отказ осознанным или случайным, и дает следующему агенту повод начать заново то, что вы уже исключили.
Этот запрет сформулирован здесь и в документации к самой диаграмме ровно потому, что инструмент предоставляет такую операцию. Правило, рассчитанное на то, что команду просто никто не заметит, — это не правило.
Операции движка — это не вызовы CLI
✎ Edit TR
Изменять bean могут две разные сущности, и шаг, путающий их между собой, будет декларировать действие, которого он на самом деле не оказывает.
Движок рабочих процессов (workflow engine) выполняет claim, note и resolve
над собственным bean экземпляра процесса при завершении шага, помеченного
как <cat-harness.processes:bean op="…"/>.
claim устанавливает статус in-progress и является идемпотентным; note добавляет запись;
resolve переводит bean в статус завершенного только тогда, когда завершился сам
экземпляр процесса, поскольку решение о готовности работы требует оценки и bean не закрывается
по чужой указке.
Агент делает все остальное через CLI beans: создание, списание,
переименование, фиксацию блокировки. В движке нет операций ни для одного из этих действий.
Это различие вовсе не гипотетическое. Одно из действий на диаграмме CRDM
содержало <cat-harness.processes:bean action="create"/> — атрибут action вместо op,
который считывает движок, — из-за чего оно было разобрано как полное отсутствие операции.
Шаг заявлял, что согласование создает beans, но на самом деле ничего не делал, причем
происходило это молча, пока кто-то не изучил парсер.
Добавляя шаг, помеченный для работы с bean, используйте одну из трех операций,
реализованных в движке, и указывайте в документации к шагу, какие именно части
являются собственными вызовами CLI со стороны агента. Скрипт bun run cat check:workflow-refs
обнаружит неразрешимую ссылку на навык, но не сможет отловить правдоподобный атрибут,
который движок никогда не читает.
Задачи для людей (todos) — еще не реализованы
✎ Edit TR
Еще не реализованы, и об этом сказано здесь прямо, а не оставлено как пробел, на который кто-то должен натолкнуться сам.
Для задач человека (todos) нужен собственный жизненный цикл, и пока ничего из этого нет:
- Когда показывать задачу. Показ каждого открытого пункта на каждой реплике диалога — это информационный шум; не показывать ничего — список, который никто не читает. Каким бы ни оказалось это правило, оно не совпадает с праймингом плана работы, который агент получает в начале сессии.
- Когда человек может создать задачу и через что — чат, команду или стартовый интерфейс сессии.
- Как задача снимается. Отказ человека от напоминания — обычное дело, не требующее раздела «причины списания»; правила для beans здесь неприменимы.
Пока это не спроектировано, не пытайтесь приспособить beans для этих целей. Хранилище, записи в котором резервируются сессиями, закрываются со сводкой изменений и никогда не удаляются, не подходит по своей структуре для напоминания, которое человек хочет отбросить без лишних церемоний — а их смешение приведет к тому, что в плане работы агентов окажутся пункты, с которыми ни один агент не должен работать.
Текущее состояние плана работы
✎ Edit QA TR
Остальная часть страницы объясняет, чем bean является. В этом разделе показано,
что хранилище сейчас содержит — данные считываются в режиме реального времени из
/assets/beans/index.json, проекции, которую
gen-docs-pages.ts формирует из beans/defs/ при каждой сборке, наряду с индексом todo,
публикуемым уже давно.
До 20.09.2026 здесь нечего было показать. Для todos/ существовали модуль чтения,
опубликованный индекс и доска поверх него; у beans/ не было ничего из этого, хотя это
хранилище на два порядка крупнее. План работы, на который никто не может взглянуть, —
это план, который никто не проверяет.
Что отображает дашборд и почему каждая панель оформлена именно так. Количественные показатели служат заголовком, поэтому они представлены числами, а не диаграммой из четырех столбиков, сообщающих одно и то же. Распределение по эпикам отображает масштаб по сущностям с длинными именами, поэтому оно выполнено в виде горизонтальной полосы. Замечания (findings) занимают три-четыре строки, поэтому они представлены списком — со значком и текстовой меткой в каждой строке, поскольку цвет статуса никогда не несет смысл в одиночку.
Замечания вычисляются только на основе зафиксированных данных, и одно из них намеренно
пропущено. Детектор зависших задач со статусом in-progress должен был бы сверяться
со временем, а проекция контролируется по точному содержимому: все, что вычисляется
относительно времени, меняет файл при каждой сборке, и контроль актуальности тогда будет
срабатывать бесконечно. Поэтому проекция публикует поле updated_at каждого bean как
неизменный факт, а страница рассчитывает возраст при ее открытии. Таким образом, возраст
изменяется без изменения самого файла, что принципиально верно.
Существует более подробное представление, доступное для навигации. Каждый объявленный
граф состояний получает собственный визуализатор по пути, который этот инстанс уже
использует для данного графа — /beans/, /todos/ и отдельный для каждого из остальных.
Этот маршрут не придуман этой страницей: bean o7eq содержит указание владельца о том,
что визуализированный артефакт адресуется по имени его инстанса с объявленным графом
в качестве сегмента пути, а также о том, что данный инстанс опускает собственное имя,
поскольку именно его каталог docs/ отдает сайт. Кроме того, навык harness-requirements
явно закрепляет этот URL как обязательство — «требованием к ним является предоставление
визуализаторов, доступных по адресу <base-url>/beans». Общего индекса над ними нет,
поскольку / принадлежит сайту документации, поэтому каждая страница просто перечисляет
соседние страницы.
Граф без проекции прямо сообщает об этом. qa, health, issue-marks и
uploads — это объявленные графы состояний, для которых проекции пока никем не публикуются.
Их дашборды прямо говорят об этом и указывают на bean 2krx, вместо того чтобы
отображать нули для хранилища, которое никто не читал: дашборд, открывающийся с нулями,
неотличим от хранилища, в котором ничего нет, а это противоположные факты.
Каждый идентификатор на этих страницах — это ссылка. Идентификатор bean ведет на файл bean, номер issue или pull request — в репозиторий на forge, а каждое замечание снабжено карандашом, ведущим к месту, где фактически происходит редактирование. Ссылка, которую невозможно разрешить, остается обычным текстом, что наглядно показывает разницу между «перейдите сюда» и «это указывает туда, куда не удалось перейти».
Чего здесь нет. Того, где именно bean находится в процессе BPMN, что составляет
вторую половину bean v49e. Для этого объединения необходим каталог beans/workflows/,
объявленный граф workflow-state, а он пуст — поэтому отображение позиции сообщало бы
«нигде» для каждого bean в хранилище. Это ожидает появления состояния экземпляров.
Интерактивный дашборд плана работы требует JavaScript. Проекция, которую он считывает, — это обычный JSON-файл, и его можно читать напрямую.