Skip to content
Back to skills

Mila Tasks

ASecurity

Система обязательств Милы Админ — как задача попадает в работу, где живёт, какая берётся следующей, чем доказывается закрытие. Использовать в начале и в конце каждой сессии, при любом поручении владельца, обещании человеку и перед любым «сделано».

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
toolsgitapi

Works with

  • api

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add shakhruz/mila-companion --skill mila-tasks --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mila Tasks?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Mila Tasks
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shakhruz-mila-tasks-mila-companion/badge)](https://www.skillsdirectory.com/skills/shakhruz-mila-tasks-mila-companion)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: mila-tasks
description: Система обязательств Милы Админ — как задача попадает в работу, где живёт, какая берётся следующей, чем доказывается закрытие. Использовать в начале и в конце каждой сессии, при любом поручении владельца, обещании человеку и перед любым «сделано».
---

# УЛИКА — управление обязательствами Милы

**Когда применять:** всегда, когда кто-то чего-то от нас ждёт, — и в начале и в конце каждой сессии. Если работа не оставила строки здесь, её не было; если строка закрылась без улики, она не закрылась.

Это **формат записи, а не движок**. Он ничего не запускает сам, ночью не работает, в чужие репозитории не коммитит. Работу делаю я, руками, в сессии. Выключить систему можно, удалив один скрипт, — файлы останутся читаемыми глазами.

---

## 1. Три сущности, а не один список

Затор был не в исполнении, а в том, что реплики, ходы, стройки и вопросы владельцу лежали в одном списке. У них разные часы и разные улики — значит, это разные вещи.

| Сущность | Что это | Часы | Чем закрывается |
|---|---|---|---|
| **обязательство** — `ход` (≤2 ч) / `стройка` (сутки–недели) | работа с приёмкой | `due`, если есть | `proof`, исполненный машиной |
| **обещание** — `promise` | «пришлю до вечера», «вернусь через час» | `due` — абсолютное время, **чужие часы** | доставленное сообщение с `message_id` |
| **развилка** — `ask` | ждёт слова, доступа или рук владельца | `deadline` + `default` | строка в `DECISIONS.md` |

**Реплика задачей не становится** — ответила и забыли. Но если в ответе прозвучало обещание, обещание заводится в ту же минуту. Именно здесь теряется больше всего: 63 входящих в сутки, задачей становится 7.

---

## 2. Как задача попадает — по источникам

**Голос владельца.** Расшифровка целиком уезжает в `archive/voice/ГГГГ-ММ-ДД-ЧЧММ.md`. Дальше **одна строка на каждый пункт, дословной цитатой**: 12-минутная надиктовка 31.07 дала пять пунктов, одна карточка на голосовое — заведомая потеря. Непонятное записываем непонятным, осмысляем после записи, не вместо неё.

Сразу за этим — **расписка, до содержательного ответа**:
`взяла: M-126 прайс · M-127 YouTube · M-128 Time Machine`
Это единственный принудитель с внешним свидетелем: не завела — он видит пропуск в ту же минуту. Правило «в ту же минуту» уже существовало и ломалось ровно потому, что свидетеля не было.

**Текст владельца.** Повелительное наклонение или срок → строка в ту же минуту, с якорем `msg:<chat>/<id>`. Якорь обязателен: через неделю «топливо на сайте» будет значить то, что решила я, а не то, что сказал он.

**Группы (28 чатов, отвечаем всем).** По умолчанию — ничего. Строка заводится, только если от нас ждут ответа или действия, либо названы срок, деньги, клиент. Шум не должен порождать карточки.

**Клиент.** Обещание заводится **руками**, не автоматом на каждое входящее: автомат на «спасибо» за неделю набьёт `PROMISES` сорванными обещаниями, которых никто не давал, и счёт репутации обесценится инфляцией. Завели — часы идут, канон ≤1 час даже ночью.

**Директора флота (29% потока).** Эскалация принимается в трёх видах: `--need decision | access | hands`. «Посоветуй» отбивается ответом в чат и задачей не становится. Файловый вход — каталог `./inbox-directors/` **вне git** (десять писателей в файл под git = конфликты слияния как штатный режим), забирается командой `task.py pull`.

**Сама нашла.** `--src self` обязателен и виден в вечерней карточке. Плюс: самонайденное без числа (`--bleed 60/сут`) не может обогнать поручение владельца. Ровно на этом сгорел MilaPM — все пять его закрытых дел были собственной гигиеной.

---

## 3. Где живёт

```
./tasks/ledger.jsonl   ← ИСТИНА. append-only, git. Строку нельзя править и удалять
./tasks/OPEN.md        ← генерится из леджера. В шапке: «править через ops/task.py»
./tasks/proof/<id>-<ts>.txt   ← вывод исполненных улик
./ops/task.py          ← шесть команд, ~250 строк, без зависимостей
./inbox-directors/     ← вне git, входящее флота
./NOW.md               ← блок между <!-- tasks:begin --> и <!-- tasks:end -->
```

Строка события:

```json
{"ts":"2026-08-03T09:12:31+05:00","ev":"new","id":"M-0142","kind":"build","src":"owner",
 "who":"<id хозяина>","anchor":"voice:2026-08-03-0910.md#3","title":"Два контура Милы Ташкент",
 "check":"health отдаёт contours=2","verify":"ssh prod 'curl -s localhost:19011/health | jq .contours'",
 "due":null,"bleed":null}
```

Событий шесть: `new · take · note · done · drop · promise/keep/broken`. Больше не нужно.

**Почему переживает перезапуск:** каталог не привязан к session-uuid и лежит в git. Задачи терялись в `~/.claude/tasks/<uuid>/` — 39 стёрты молча, 12 остались в мёртвых папках. Теперь `~/.claude/tasks/` — **черновик текущего дня**, ≤5 строк, умирает вместе с сессией, и это нормально. `TaskList` не вызываем никогда: 18–30 тыс. токенов за взгляд против 2 тыс. у `task.py open`.

**Ужим `NOW.md` больше не может ничего съесть.** Блок генерируемый; что не влезло — печатается строкой «скрыто 14, полностью в OPEN.md». Пункт «четыре навыка» исчез бесследно при ужиме 163→80 строк — потому что урезание было невидимым.

**Один реестр, ни дня двух.** `ROADMAP.md` в первый же день получает шапку «архив до 03.08, живая очередь — `tasks/OPEN.md`», `INBOX.md` упраздняется. Три реестра разошлись на 17 задач за трое суток именно от параллельного ведения.

`git commit` — в конце сессии, локально и безусловно. `push` — отдельным асинхронным проходом. Синхронный push в каждой записи превращает сетевой сбой в остановку учёта, а живая реакция на неудобный инструмент одна — вести работу мимо него.

---

## 4. Какая берётся следующей — правило, не интуиция

`task.py next` печатает одну задачу и причину выбора. Правило лексикографическое: первая непустая корзина выигрывает целиком, внутри — по возрасту, старшая первая.

1. **Сорванное или горящее обещание человеку** (`promise`, `due < now+60m`). Всегда первое: это чужие часы, тихие часы на них не действуют.
2. **Кровь и срок:** заполнен `bleed` (измеренная утечка числом) · взяты деньги · `due` сегодня или в прошлом.
3. **Сказал сегодня** (`src=owner`).
4. **Всё остальное**, и **строка старше 10 суток без касания поднимается наверх этой корзины сама**. Ритуал «раз в неделю пересмотреть залежавшееся» не нужен: ритуал, который надо помнить, заменяется сортировкой, которую помнить не надо.

**Три жёстких потолка, их держит скрипт:**
- В работе одновременно ≤3, из них **ровно одна стройка**. Стройка съедает сессию целиком — притворяться иначе значит потерять и стройку, и ходы.
- **Один слот стройки в сутки**, и он берётся до первой улики. Без слота стройки не двигаются вообще: 22 из 42 открытых старше трёх суток.
- Задача в работе без `note` за 24 часа падает обратно в очередь с меткой `stalled` и печатается на старте сессии. Статус, который ничего не значит, хуже отсутствия статуса.

---

## 5. Что считается закрытием

**`task.py done` без `--proof` завершается с кодом 2 и не пишет ничего.** Это запрет, на котором держится всё остальное.

**`check` и `verify` пишутся при заведении, а не при закрытии.** Иначе «сделано» определяет тот, кто делал. `new` без `check` отказывает.

**Улику исполняет скрипт, а не печатаю я.** `done` перезапускает `verify` прямо сейчас, кладёт в `proof/` команду, exit-code, первые строки вывода и время. Напечатать «curl → 1», не запустив curl, больше нельзя — а это был бы главный способ соврать.

Формы улики:

| Форма | Что делает `done` |
|---|---|
| `cmd:` / `probe:` | выполняет, сохраняет вывод и код возврата |
| `url:` | код 200 **и** grep отпечатка из `check` в теле ответа |
| `msg:<chat>/<id>` | ищет файл в `channels/telegram/sent/`, сверяет `chat.id` с адресатом карточки, отвергает при наличии того же текста в `failed/` |
| `git:` | sha в origin **плюс** отдельная проверка на бою |
| `human:` | цитата ответа человека и его `message_id` |

Три правила поверх:
- **Улика должна пересекаться с текстом `check`.** Проверяем не то, что улика существует, а то, что она доказывает обещанное.
- **`git:` ≠ выкачено.** Правка от 14.07 с «deployed» в теме коммита не работала 19 дней.
- **Клиентская задача закрывается только чужой рукой** — `human:` или `msg:`. Свой прогон не доказывает, что клиенту стало хорошо.

**Третий исход обязателен.** Не «прошло / отвалилось», а **«не смогла проверить»** — прод недоступен, токен протух, Мак спал. Такое пишется `unknown` и звучит громко: «проверено 5 из 14, 9 не проверялись». Тишина обязана значить ровно одно.

**`--force`** (принято со слов, машина не проверила) остаётся в строке навсегда и отдельной строкой в вечерней карточке: «закрыто 7, из них 1 без машинной проверки».

**Провал требует улики так же, как успех.** «Упёрлась в API» без лога и кода ответа — бесплатный способ не делать работу.

**`drop` требует `--why` и остаётся в леджере.** Но задачу владельца или клиента дропнуть нельзя — она уходит развилкой за его словом. Тихое списание чужого поручения — то, за что MilaPM потерял доверие.

**В карточке не «закрыто 4», а перечисление сутью.** Число дробится: разбил стройку на пять ходов — цифра выросла вдвое, честности не прибавилось. Перечисление выдаёт себя само.

---

## 6. Обещания — отдельная сущность с часами

Обещание заводится **до отправки сообщения, в котором оно звучит**:
`task.py promise --to <chat> --who "Наталья" --what "прайс" --due "03.08 18:00"`

Закрывается только `task.py keep --msg <chat>/<id>` — доставленным сообщением. «Отправила» ≠ «дошло»: в `failed/` лежит больше тысячи неотправленных.

Сорванное обещание **не удаляется никогда**: остаётся в разделе «сорвано» и обязано прозвучать в вечернем касании раньше, чем человек заметит сам. Это счёт репутации, а не мусор.

**Сторож — пишущий, не блокирующий.** Хук `PostToolUse` на исходящих пишет `message_id` в леджер. Раз в день `task.py scan-sent` перечитывает наши исходящие за сутки и помечает похожее на обязательство («пришлю», «сделаю», «до пятницы», «завтра») — каждое совпадение надо пометить «карточка есть» или «не обещание». Блокировать отправку нельзя: одно ложное срабатывание в 23:40 на живом клиенте — это отказ продакшена, и вслед за ним рубильник, который снесёт всю систему.

И честно: сторож стоит на одном пути отправки из трёх. Значит **гарантии «обещание не растворится» у нас нет** — есть ловушка, которая ловит большую часть. Обещать больше, чем механика держит, опаснее самой дыры: под гарантию перестают смотреть глазами.

---

## 7. Что ждёт владельца

Три разных ожидания — три разных обращения.

**Развилка `ask`.** Команда отказывается работать без `--a`, `--b`, `--default`, `--undo`, `--deadline`. Вопрос без дефолта — это домашняя работа, а не вопрос.

- **Дефолт — самая дешёвая отменяемая ветка, а не «ничего не делаем».** Иначе «первые касания 18 тёплым» по умолчанию превращается в «не пишем никому», и ровно те развилки, что стоят денег, дефолтятся в бездействие.
- **Часы идут от подтверждённой доставки** (`message_id` есть). Не дошло — таймер стоит, строка уходит в «твои руки». Иначе в `DECISIONS.md` появится решение, которого человек не принимал, — это подделка подписи, а не потеря задачи.
- По истечении срока `autodecide` исполняет дефолт и пишет честной формулировкой: «принято Милой по умолчанию, показано 03.08 08:31 msg 41207, ответа не было 48 ч, отменяемо одним словом».
- **Потолок — 3 открытых.** Четвёртый `ask` отказывается со словами «сначала закрой один», и сам отказ пишется в леджер и звучит в карточке: очередь не должна выглядеть здоровой оттого, что вопросы подавлены. У MilaPM она выросла 13→49, и слово «закрыто» встретилось в ней один раз.

**Необратимое** (деньги, публикация наружу, юридическое) дефолта не имеет — становится строкой с **ценой ожидания**, которая печатается каждый раз: «Окно TG Business: ждёт 4 дня · сгорело ~240 контактов из 376 · осталось 136». Цена ожидания — число из команды, а не из головы.

**Твои руки** (`--need access | hands`): карта, ключ, токен, доступ к каналу, Time Machine. Это не вопросы, их нельзя спрашивать по одному. Один хвост в утреннем сообщении, максимум пять строк, у каждой — дни ожидания и цена простоя. Растёт число дней — растёт цена в строке. Это единственное давление, которое вообще возможно.

---

## 8. Ритуалы

**Старт сессии — `task.py open`** (≤60 строк, ~2 тыс. токенов):
1. красной строкой — если вчерашний день не закрыт или за сутки в леджере нет ни одного `done`/`note`;
2. сорванные и горящие обещания;
3. что решено по умолчанию с прошлой сессии;
4. `stalled` — висящие в работе без записи;
5. `next` — пятёрка с причинами;
6. **перепроверка трёх случайных закрытий**: сессия начинается с недоверия к себе.

**Конец сессии — `task.py close-session`:** печатает всё, что в работе без улики, дописывает `CHANGELOG.md` из событий `done`, регенерит `OPEN.md` и блок в `NOW.md`, коммитит. **Печатает, но не блокирует.** Отказ завершать сессию ничего не стоит: сессия просто кончается, не вызвав команду. Работающий принудитель один — вечерняя карточка на глазах владельца: пустая — он спросит.

**Сторож снаружи.** Единственная автоматика первой недели: если за сутки в леджере ноль событий `done` и `note` — красная строка в утреннем сообщении. Система обязана жаловаться на себя вслух, иначе её молчание неотличимо от нормы. Каждый скрипт пишет `last_run`, и `open` первой строкой печатает «scan-sent не отрабатывал 3 дня». Уже проходили: сторож Мака сам был мёртв, алерт кричал 1440 раз в сутки, и его не читал никто.

---

## 9. Что видит владелец

Три касания в сутки, каждое ≤12 строк, строка ≤200 знаков. Тихие часы 22–08 — молчание, кроме утечки наружу, уходящих денег и сорванного обещания клиенту. Красное определяется списком меток, а не моим суждением.

**08:30 — лист дня.** Что беру (одна стройка + три хода) · что горит · один вопрос с дефолтом и сроком · хвост «от тебя, когда будешь у машины».

**14:00 — только если есть красное или готовая улика.** Иначе тишина. Норма — тишина.

**21:30 — касание улик.** Ни одного слова без доказательства: закрытое перечислением с кликабельной уликой · сорванные обещания · что решено по умолчанию · что не пошло и почему · «перепроверено N, отвалилось M, не проверялось K».

**Тело карточки собирается шаблоном из событий.** Свободная фраза допустима только в блоке «мнение», и **цифр в нём быть не может** — сводка уже врала ровно так: вывод разошёлся с исходником.

**Чего владелец не увидит никогда:** карточек «▶️ взяла в работу» (у MilaPM их 157 из 353 — чистый шум), простыней на 1200 знаков и внутренних поломок самой системы. Свою поломку пишу в лог и останавливаюсь.

---

## 10. Чего не делаем

Урок MilaPM: 225 оборотов, 64.9 часа машинного времени, 353 карточки за восемь дней — и один `ROLLED_OUT`. Все пять «подтверждённых» дел оказались его собственной гигиеной, поручения владельца ушли в DROPPED, 61 вопрос остался без ответа. **Он строил себе учёт, пока продукт стоял.** Второй раз этот кредит не выдадут.

Поэтому:

- **Никакого демона.** Ни ночных петель, ни параллельных обортов, ни веток и worktree в чужих боевых репозиториях. Один скрипт, один пишущий хук, один утренний печатающий крон.
- **Не строим учёт вперёд работы.** Пока формат не прожил вручную три дня, кода нет. Скрипт появляется, когда видно, какие три команды из пятнадцати реально нужны, — тогда это 250 строк, а не 400.
- **Не блокируем.** Ни отправку клиенту, ни завершение сессии, ни коммит. Блокирующий хук на боевом пути живёт до первого ложного срабатывания, а потом уносит с собой всю систему одним `mv`.
- **Не автоматизируем захват регэкспами.** Ночной grep по повелительным формам родит призрачные задачи из чужих разговоров, реестр загрязнится тихо и заметим через неделю.
- **Не тянем чужие бэклоги.** 47 строк бэклога мёртвого движка — это его гигиена, а не наша работа. Берём поручения владельца, остальное не наследуем.
- **Не заводим статусов вроде PARKED.** Есть развилка (с ценой и сроком) и `drop` (с причиной). Третьего нет — «отложено навсегда» это 52 карточки, о которых никто не вспомнит.
- **Не делаем ритуалов, о которых надо помнить.** Воскресный пересмотр, месячная архивация, недельные аудиты — заменяются сортировкой и порогом. Первый пропущенный вечер убивает ритуал, порог не пропускается.
- **Не обещаем гарантий шире покрытия.** «Физически не может потеряться» — только там, где это правда.

---

## 11. Первый час — без единой строки кода

1. **Семь развилок из `ROADMAP.md`** (они стоят с 31.07, ответа не было ни на одну) получают по три поля: дефолт — самая дешёвая отменяемая ветка · срок · откат. Уходят владельцу одним сообщением: **три штуки**, остальные ждут. Молчание до срока = исполнен дефолт, строка в `DECISIONS.md`. Это размораживает четверо суток простоя сегодня же.
2. **Один экран «твои руки»** — карта Tribute · прайс Иззатиллы · YouTube · Time Machine · токены ботов-отцов · права в двух группах. У каждой строки дни ожидания и цена простоя. Отправить в утреннем сообщении.
3. **Завести `./tasks/ledger.jsonl`** и перенести туда **десять живых** задач руками, в том же json-формате: `title`, `src`, `check`, `verify`, `due`. Не 53 и не 47 — остальные лежат в архиве и всплывут, если понадобятся. Массовый импорт даст стену диспозиций на первой же сессии, и она превратится в штамп.
4. **`ROADMAP.md` и `INBOX.md` в тот же час получают шапку «архив, живая очередь — tasks/OPEN.md».** Двух реестров не должно быть ни дня.
5. **Четыре красные разобрать отдельно и до системы** (задача с сорванным сроком, оплаченный заказ без исполнителя, инструмент без авторизации, окно интеграции, которое закрывается). Разбирать их внутри миграции нельзя: иначе через неделю не отличить пользу формата от пользы «наконец дошли руки».
6. **Вечером — карточка улик по новому образцу.** Она и есть первый принудитель.

Скрипт `ops/task.py` — завтра, шестью командами: `new · take · note · done · promise/keep · ask`. Первым пишется исполнитель улики: `done` запускает `verify` и сохраняет вывод. Он опирается на замер, а не на теорию.

**Метрика недели, доступная с третьего дня:** сколько закрытий несут улику, исполненную машиной, и сколько развилок закрылось без владельца. Не сдвинулось — система театр, каким бы красивым ни был формат.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.