План работы
Список того, что в идущей работе ещё не сделано: фазы, нумерованные задачи и ровно одна взятая в работу. Ведёт его Ева сама; просить план у Господина не надо.
Смысл не в галочках. Длинный тур теряет вторую половину задачи молча: окно живой истории сворачивается в резюме, выхлоп инструментов из начала тура схлопывается до огрызка, и «а ещё надо поправить книгу» исчезает вместе с ними. План этого не переживает — он живёт в базе и приезжает в промпт заново каждым ходом.
Чем это не блокнот
Блокнот — про факты, которые переживают работу: решение и почему, инвариант проекта, путь, добытый раскопками. План — про незавершённое, у него есть инвариант, и он обязан исчезнуть по завершении дела. Смешать их значит забить блокнот мёртвыми галочками и задавить ими выдачу.
Инвариант
Ровно одна задача в работе. Держится кодом, а не просьбой в промпте:
startснимает активность с прежней задачи;- после любой операции активных не осталось — активной становится первая
pending; - активных вдруг несколько — остаётся первая, прочие возвращаются в
pending.
Ошибочная ссылка на несуществующую задачу или фазу откатывает всю операцию и возвращается ошибкой с перечнем живых номеров и фаз: полусделанная мутация хуже отказа. Технически список считается в памяти целиком и пишется целиком — состояния «половина применилась» не бывает.
Жизнь плана
| когда | что происходит |
|---|---|
| вход в тур | закрытые и брошенные задачи вычищаются: список — про оставшееся |
| в туре | ответ каждого вызова — состояние плана целиком, а не «ок» |
| конец тура | план, в котором не осталось незакрытого, стирается вместе с последней галочкой |
Стереть план руками — init с пустым списком задач или
DELETE /v1/chats/{id}/plan.
Когда инструмент виден
Не всегда. Пустой план в обычной болтовне — строка мёртвого веса в каждом
запросе и соблазн расписать «поздороваться / ответить». turn_plan даётся
туру Господина, который к тому же:
- ведёт клиентские операции (кодовая сессия клиента),
- работает в наборе с
narrate(кодовые и инфраструктурные наборы), - либо это тур подагента,
- либо план в чате уже открыт — недоделанное нельзя спрятать.
Прячется он штатным гейтом реестра (Tool::planning_only, наравне с
master_only), а не отдельным фильтром: мимо гейта он остался бы в реестре
скрытого, и модель вытащила бы его tool_load’ом ровно там, где план и
есть мёртвый вес.
Операции
Одна операция на вызов, дискриминатор op на верхнем уровне — массива
операций нет: модель видит состояние после каждой правки.
op | что делает |
|---|---|
init | заменить план целиком; пустой tasks — стереть |
append | дописать задачи в открытый план |
start | взяться за задачу по номеру |
done | закрыть задачу, фазу целиком или (без аргументов) ту, что в работе |
drop | то же, но «бросить»: задача перестала иметь смысл |
view | просто вернуть план |
Задача — {title, phase?}. Фаза — просто имя группы, регистр не считается;
новая задача встаёт в конец своей фазы, незнакомая фаза — в конец
плана, поэтому дерево остаётся деревом при любой дописке. done/drop
принимают outcome — одну строку о том, чем кончилось.
Потолки: 40 задач, 120 символов на заголовок, 40 на имя фазы. Перебор — внятный отказ, а не молчаливое обрезание.
Где он в промпте
Только летучим хвостом — в блоке [state], рядом с памятью и
блокнотом. В стабильную часть нельзя: план меняется каждую итерацию и рвал
бы префикс кэша промпта каждый ход.
Выглядит деревом с отметками [ ] / [>] / [x] / [~]:
[plan] Your plan for the work at hand — 4 tasks: 1 done, 0 dropped, 3 left.
## dig
1 [x] find every call site — all in agent.rs
2 [>] read the config schema
## build
3 [ ] add the field
4 [ ] update the book
Ровно то же возвращает и сам инструмент: модель видит после правки то, что увидит следующим ходом.
Клиентам
GET /v1/chats/{id}/plan→{tasks: [{id, phase?, title, status, outcome?}]}; пустой список — плана нет. Ручка для первой отрисовки и переподключения.DELETE /v1/chats/{id}/plan→{deleted}.- Событие стрима
planс полемtasks— состояние целиком, а не дифф; прилетает на каждую правку и с пустым списком, когда план закрыт по концу тура. В историю не персистится.
Граница
Это состояние одной работы в одном чате, а не менеджер задач Господина.
Его задачи живут в кроне, очереди одобрений и папке problems — у них своя
жизнь и свои сроки.