Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: mila-tasks description: "Система обязательств агента: три сущности (ход/стройка · обещание человеку · развилка владельца), append-only леджер, закрытие только с уликой, исполненной машиной, порядок «следующая», прогноз времени и токенов, отчёт «Результат · Вопросы · План». Использовать в начале и в конце сессии, при любом поручении, обещании и перед любым «сделано»."
mila-tasks — УЛИКА
Когда: всегда, когда кто-то чего-то от нас ждёт. Работа без строки — её не было; строка без улики — не закрыта. Один скрипт, не движок: сам ничего не запускает, отправку не блокирует.
Три сущности, а не один список
| Сущность | Что | Часы | Чем закрывается | |
|---|---|---|---|---|
обязательство M-… — ход (≤2 ч) / стройка (--kind build) | работа с приёмкой | due, если есть | done --proof … — улику исполняет скрипт | |
обещание P-… | «пришлю до вечера» | due — чужие часы, абсолютное время | keep --msg <chat>/<id> — доставленное сообщение | |
развилка A-… | ждёт слова / доступа / рук владельца | deadline + default | decide (владелец или дефолт по сроку) |
Реплика задачей не становится; обещание в реплике заводится до отправки.
Где живёт
tasks/ledger.jsonl ← истина, append-only (строки не правятся и не удаляются)tasks/OPEN.md ← генерируется; править через task.pytasks/proof/ ← вывод исполненных уликtasks/estimates.json ← стартовые оценки по видам, пока фактов < 3tasks/sent.jsonl ← журнал исходящих (пишет PostToolUse-хук)ops/task.py ← один скрипт, stdlib
Каталог переопределяется MILA_TASKS_DIR (тесты гоняются во временном).
Команды
task.py new --title … --check «чем проверяется» [--verify cmd] [--kind reply|doc|translate|build|research|fix|design|report][--src owner|client|self|director] [--who] [--chat id] [--anchor msg:chat/id] [--due «завтра 12:00»] [--bleed «74/сут»] [--paid]task.py take M-0001 в работу (≤3 одновременно, одна стройка, один слот стройки в сутки)task.py note M-0001 «…» касание; без note 24 ч → stalled, назад в очередьtask.py done M-0001 --proof cmd:… | probe:… | url:адрес|отпечаток | msg:chat/id | git:sha@repo | human:цитата [--tokens N] [--force]task.py drop M-0001 --why «…» задачу владельца/клиента дропнуть нельзя — только развилкойtask.py promise --to chat --who Имя --what «прайс» --due «к 18:00» keep P-0001 --msg chat/id · broken P-0001 --whytask.py ask --title … --a … --b … --default a --undo «откат» --deadline «завтра 12:00» [--need decision|access|hands] [--task M-…] [--cost «число»]task.py note A-0001 delivered:chat/id часы развилки идут только с доставкиtask.py decide A-0001 --choice a --by ownertask.py next [--n 5] · open [--short] · scan-sent [--hours 24] · report <id> · regen · nowblock
Что держит скрипт, а не память
newбез--check— отказ. Критерий закрытия пишется при заведении, не при закрытии.doneбез--proof— код 2, ничего не пишет. Улика исполняется прямо сейчас (команда, URL с отпечатком в теле — код 200 сам по себе ничего не доказывает, сообщение в журнале исходящих с совпадением адресата и без копии вfailed/), вывод и код ложатся вproof/. Упала — не закрыто (код 3). «Не смогла проверить» — третий исходunknown, закрывается только--force, и это остаётся в строке навсегда.- Клиентская задача закрывается только чужой рукой:
human:илиmsg:. askбез А/Б/дефолта/отката/срока — отказ. Открытых развилок ≤3, четвёртая отказывается, и отказ пишется в леджер.- Порядок
nextлексикографический: сорванное/горящее обещание (due < now+60m, без срока — тоже) → кровь/деньги/срок сегодня → сказал владелец сегодня → остальное, где строка старше 10 дней без касания поднимается сама.
Прогноз времени и токенов
У каждой строки kind; estimates.json — стартовые значения с пометкой «оценка до накопления фактов». done пишет факт: минуты от take до done и --tokens, если переданы. С трёх фактов по виду прогноз становится медианой; next, open, report печатают прогноз рядом с задачей.
Отчёт — task.py report <id>
Три раздела в мобильном формате: Результат (статус с уликой или прогнозом) · Вопросы с рекомендациями (развилки А/Б с дефолтом) · План действий (следующие команды; «твои руки» отдельной строкой).
Хуки (пишущие, не блокирующие)
SessionStart→hooks/task-open.py: печатаетopen --short(≤12 строк), сорванные обещания первыми.PostToolUseна инструмент отправки в мессенджер →hooks/task-sent.py: каждое исходящее вsent.jsonl; при признаках обещания («пришлю», «сделаю», «в течение», «к вечеру», «сегодня», «завтра», «до …», «готово будет», «через …») заводитpromiseсchat_idи разобранным сроком; не разобрался —due=null, метка «уточнить срок». Лишняя карточка дешевле пропущенного обещания. Ключchat/message_id— повтор не дублирует.
Хук стоит на одном пути отправки — гарантии «не растворится» нет: ловушка на большую часть + scan-sent раз в сутки, open краснеет, если он не отрабатывал.
Чего не делаем
Демона · учёт вперёд работы · блокировку отправки и сессии · захват задач из чужих разговоров (только свои исходящие) · чужие бэклоги · статус «отложено» (есть развилка с ценой или drop с причиной).