Трекер задач, в котором работают ИИ: TaskForge, Obsidian, Syncthing и пара ассистентов

В прошлых статьях я переносил домой музыку и фотографии. Эта статья про другое: сделан свой трекер задач и пустил туда работать ИИ. Задачи живут в обычных Markdown-файлах, по одному файлу на задачу. Синхронизируются они между телефоном, ноутбуком и Linux-боксом. Читают и пишут их Android-приложение TaskForge, Obsidian, CLI, MCP-серверы и два вида ИИ-ассистентов: «Admin» (Grok Bot) на боксе и проектные сессии Claude на ноутбуке. Ниже рассказываю, как это устроено, какие правила пришлось ввести и где я наступил на грабли.
С чего всё началось
Всё началось с Google Таблиц. У каждого проекта была своя таблица-трекер: строки задач, вкладка с решениями, вкладка с вопросами. Рядом в репозиториях лежали PLAN.md, PROGRESS.md, DECISIONS.md и QUESTIONS.md. Пока агент был единственным, кто их вёл, это кое-как работало.
Потом работу проектов стали делать ИИ. Claude гонял замеры и писал код, Grok Bot следил за процессами и собирал отчёты. Обоим нужно было где-то записывать, что сделано, что решено и что ждёт меня. Результаты начали расползаться: часть оставалась в чате, часть в PROGRESS.md, часть в таблице, а часть только в контексте сессии, которая потом закрывалась и забывала всё. Я поймал себя на том, что по утрам выясняю у одного ИИ, о чём вчера договорился с другим, а склероз которым тотально страдают нейронки вообще приводил к непрерывным открытиям, что в плане двухнедельной давности половина не сделана.
Мне был нужен трекер, который одинаково удобен трём участникам. Мне на телефоне, причём с телефона я в основном и управляю. ИИ через нормальный программный интерфейс, а не через скриншоты веб-формы. И ему самому, чтобы трекер пережил любой из своих клиентов. Обычные Markdown-файлы под это подходят. TaskForge оказался приложением, которое умеет работать с такими файлами на телефоне и при этом даёт CLI и MCP-сервер для ИИ.
Трекер, в который пишут несколько ИИ, — это добровольное назначение себя администратором распределённой системы. Синхронизация файлов между тремя устройствами, на которых одновременно что-то правят, поломается обязательно. Поэтому половина статьи не про «как поставить приложение», а про правила, валидацию и сторожей, без которых всё это разваливается за пару дней.
Чего мы хотим
Мне не нужна Jira и не нужна командная работа в привычном смысле: команда здесь — это я и несколько ИИ. Нужен личный трекер, где ИИ ведут проекты, а решения остаются за мной. Отсюда цели:
- Одна задача — один файл. Формат TaskNotes: Markdown с YAML-шапкой, название задачи = имя файла. Никакой базы данных, никакого облака. Файлы читаются глазами, grep’ом и Obsidian’ом и переживут любое приложение.
- Телефон как главный пульт. Android-приложение TaskForge: посмотреть, поменять статус, ответить на вопрос, принять решение. Компьютер для этого не нужен.
- ИИ работают через API, а не руками. Каждый ассистент пишет в трекер только через MCP-сервер или CLI. Самодеятельности в YAML нет: формат знает инструмент, а не память модели. Тут нужно отметить, что я взял TaskForge CLI+MCP но у obsidian и TaskNotes есть свои, разницы для меня по сути нет.
- Трекер — единственный источник правды. Результаты замеров, решения, вопросы, логи и документы лежат в трекере или привязаны к задаче. Потому нередко можно просто отправить агента в трекер и он найдет немало новых задач, о которых забыл.
- Задача может разбудить ассистента. Ставлю задаче тег и время — в это время ИИ просыпается и выполняет то, что написано в её теле. Будильник, отложенная проверка или регулярная рутина задаются без отдельного планировщика.
- Защита от дурака, в том числе от умного дурака. Правила, которые нельзя забыть: валидация на каждой записи, ночные проверки, удаление только через карантин. ИИ иногда очень уверенно делает глупости, поэтому система должна это ловить, а не надеяться на внимательность.
- Выживание после ребута. Бокс перезагрузился (это у Grok Bot) — синхронизация, циклы и сторожа поднялись сами, а я узнал об этом одной строкой.
Архитектура
Вся установка выросла из одной мысли:
Трекер — это папка с Markdown-файлами. Всё остальное — клиенты, которые по-разному в эту папку пишут, плюс Syncthing, который пытается договориться о том, какая версия файла правильная.
ТЕЛЕФОН (Android) НОУТБУК
TaskForge-app + Obsidian Claude Code: сессии mon-g0, tq-g1, ...
один vault, 5 папок проектов taskforge CLI/MCP (обёртка bwrap)
│ interconnect (почта ассистентов, tmux)
│ │
└────────── Syncthing ──────────────┤
(send-receive, .stversions) │
│ │
═════════════════ Linux-бокс (всегда онлайн) ══════════════════
/workspace/taskforge-vaults/{admin,turboquant,monitor,liberec,proxy}
└─ Projects/<Name>/ (реальная папка Syncthing: задачи, Archive/, attachments/)
▲
│ stdio
taskforge-mcp-proxy (--validate, 8 правил) ──► taskforge mcp --stdio
▲
Admin (Grok Bot) ◄── tt-loop (раз в минуту: теги agent, напоминания, precheck)
▲ selftest 23:50 · validate_vault 03:17 · сторож Syncthing
└── рутина раз в 10 минут: письма Claude + сработавшие задачи
На схеме важны две вещи. Во-первых, у файлов нет главного: телефон, ноутбук и бокс равноправны, и Syncthing по очереди тащит изменения от каждого. Это удобно, пока все правят разное, и превращается в отдельный жанр, когда двое правят одно и то же (см. «Грабли»). Во-вторых, ИИ пишут в трекер только через инструменты. Admin на боксе работает через MCP, обёрнутый в валидирующий прокси. Claude на ноутбуке работает через свой CLI/MCP. Ни один ИИ не сочиняет YAML руками.
| Компонент | Где живёт | Роль |
|---|---|---|
| TaskForge (Android) | телефон | Главный пульт: смотреть, менять статусы, ставить напоминания, принимать решения |
| Obsidian | телефон, ноутбук | Читать и связывать задачи как заметки, смотреть граф ссылок |
taskforge CLI / taskforge mcp --stdio |
бокс, ноутбук | Программный доступ к задачам: запросы, создание, правка полей, закрытие |
taskforge-mcp-proxy |
бокс | Прослойка между ИИ и MCP: подставляет пространство и проверяет каждую запись по 8 правилам |
| Syncthing | телефон, ноутбук, бокс | Синхронизация 5 папок проектов и общих настроек TaskForge |
| tt-loop + selftest | бокс | Будит ассистента по задачам с тегом agent, ночью проверяет сам себя |
| Admin (Grok Bot) | бокс | Ведёт трекер, управляет сессиями Claude, следит за синхронизацией |
| Сессии Claude | ноутбук (tmux) | Делают проектную работу по группам задач и пишут результаты в трекер |
| interconnect | ноутбук | Файловая почта между ассистентами и управление tmux-сессиями Claude |
Проектов пять, и у каждого свой vault, свой MCP-сервер и своя папка Syncthing:
Свой MCP потому, что мне нужно было внутри одного Obsidian vault на телефоне расшарить на другие устройства подпапки через syncthing и каждому проекту назначить свою папку на боксе (grok bot и ноутбук с Claude), а taskforge MCP такое не может сам по себе, так что пришлось обойти.
- admin — задачи самого Admin по управлению проектами: запуск сессий, сверки, рутины, правила;
- turboquant — эксперименты с квантованием KV-кэша для локальных LLM (замеры, порт, сборки);
- monitor — проект сервиса мониторинга;
- liberec — бытовой личный проект, его ведёт отдельный ассистент;
- proxy — подпроект прокси памяти для Claude Code.
По данным ночной проверки сейчас в них чуть больше двух тысяч задач вместе с архивом. Тысяча с лишним приходится на один Monitor, и это хорошо показывает, сколько мелких шагов набирается, когда каждый шаг ИИ становится задачей. При этом ИИ забывает обычно 95% на долгом проекте.
Шаг 0. Формат: одна задача — один файл
TaskNotes — это простой формат. Задача = файл .md, метаданные в YAML-шапке, тело — свободный Markdown. Название задачи хранится в имени файла, ключа title нет. Вот как выглядит типичная задача:
---
status: open
priority: normal
due: 2026-10-10
scheduled: 2026-10-09
dateCreated: 2026-10-08T20:44:57.215+02:00
tags:
- task
contexts:
- pc
projects:
- "[[TurboQuant]]"
timeEstimate: 15
onCompletion: archive
taskSourceType: taskNotes
dateModified: 2026-10-08T20:44:57.215+02:00
id: muzvyzun
---
Короткое описание, что сделать, и критерий готовности.
Материалы: [[attachments/Название отчёта]]
Несколько деталей, о которых стоит знать заранее:
- Файл считается задачей, только если в
tagsестьtask. Без этого тега файл — просто заметка. id— это base36 от времени создания. Он не меняется никогда, даже при переименовании, и машинные ссылки (depends_on) идут по нему.projectsсо ссылкой на другую задачу означает «подзадача».blockedBy— это список зависимостей «нельзя начать, пока не закончено то».- Закрытая задача с
onCompletion: archiveпереезжает вArchive/. Переносит её TaskForge на телефоне или инструмент, но никогда не ИИ руками. - Из имени файла вырезаются
/ \ : * ? " < > | # [ ] ^, а кириллица и пробелы остаются. Заголовок «Решение: да/нет?» превратится в имя файла, по которому потом не найдёшь ни одну вики-ссылку.
Структура vault’а одинаковая у всех пяти проектов:
Тут нужно понимать, что это структура на компе Grok Bot в облаке, на моем телефоне где работает TaskForge это один vault, а это сделано как раз потому, что taskforge cli не поддерживает указание отдельных пространств (термин TaskForge) с задачами по разным папкам. Мне нужно было что бы агенты копаясь в своих задачах чужие не трогали.
/workspace/taskforge-vaults/<проект>/
├── Projects/<Name>/ ← реальная папка Syncthing
│ ├── *.md ← активные задачи
│ ├── Archive/ ← закрытые
│ └── attachments/ ← документы: docs/, history/, research/, runs/<run-id>/
├── TaskNotes/Archive → symlink в Projects/<Name>/Archive
└── TaskForge/Settings → symlink на общие настройки (dialect.json, spaces.json)
Папка проекта должна быть настоящей, а не симлинком: TaskForge CLI не индексирует задачи, до которых добирается только через симлинк. На ноутбуке у Claude по той же причине стоит маленькая обёртка taskforge-project. Она через bwrap монтирует реальную папку Syncthing внутрь vault-обёртки в приватном пространстве имён и подкладывает свою копию dialect.json, где папка новых задач указывает в проект, а не в несинхронизируемый TaskNotes/Tasks:
# taskforge-project <turboquant|monitor|proxy> <аргументы taskforge>
exec bwrap --bind / / --dev-bind /dev /dev \
--bind "$R" "$V/Projects/$N" \
--ro-bind "$O" "$(readlink -f "$DL")" \
--die-with-parent "$HOME/.local/bin/taskforge" "$@"
Без sudo, ничего не перемещается, общий файл настроек телефона не меняется. Но это просто “как агент придумал”, я не критиковал его, работает и ладно.
Ещё одно правило, которое я ввёл не сразу: всё содержимое трекера пишется по-русски. Это касается названий, тел, логов и решений, кто бы их ни писал. Между собой ассистенты переписываются по-английски, но всё, что читаю я, должно быть по-русски. В трекере я читаю всё, поэтому он русский. Но то, что агенты обязаны говорить между собой ао английски экономит токены.
Шаг 1. MCP: ИИ пишет только через инструмент
Главное правило установки звучит так: формат задач знает инструмент, а не ИИ. Модель уверенно напишет YAML «по аналогии», перепутает in_progress с in-progress. Каждая такая мелочь ломает приложение на телефоне. Поэтому любые правки задач идут только через MCP-сервер проекта, а если его нет — через CLI. Руками файл не редактирует никто.
На боксе работают пять MCP-серверов, по одному на vault: taskforge-admin, taskforge-turboquant, taskforge-monitor, taskforge-liberec, taskforge-proxy. Все они запускаются одинаково, через прокси:
command: python3
args: /workspace/agent-tools/taskforge-mcp-proxy/proxy.py \
--vault /workspace/taskforge-vaults/<имя> --default-space <имя> --validate
env: TASKFORGE_VAULT=/workspace/taskforge-vaults/<имя>
Важная мелочь: taskforge mcp игнорирует --vault и берёт путь только из переменной окружения TASKFORGE_VAULT. Прокси выставляет её сам и без хранилища не стартует.
Как ИИ работает с задачей:
- Перед первой записью в сессии вызывает
get_dialect. Это машинное описание настроек vault’а, которое приложение генерирует само: какие статусы есть, как они пишутся в файл, где архив. Например, MCP-токенtodoпишется в файл какopen, аmedium— какnormal. - Находит задачи через
query_tasks(status:in_progress path:^Projects/Turboquant/ text:"..."). - Меняет задачу через
update_task, и меняет точечно: статус отдельно (set_status), зависимость отдельно (add_depends_on), лог отдельно (append_note). MCP не переписывает файл целиком, а меняет конкретное поле, сохраняя всё остальное, включая ключи, которых он не знает. - Передаёт в каждую правку
if_hashиз последнегоget_task. Если хэш не совпал, значит, файл успел поменяться, обычно потому, что я в этот момент правил задачу на телефоне. Тогда ИИ перечитывает задачу, пробует ещё раз и, если снова не вышло, останавливается и сообщает мне.
Последний пункт оказался важнее, чем выглядит. Без if_hash ИИ спокойно затирает правку, которую я сделал на телефоне минуту назад.
Шаг 2. Валидирующий прокси: восемь правил, которые нельзя забыть
Правила в инструкциях ИИ работают примерно как правила в офисной вики: все читали, никто не соблюдает. Поэтому через несколько дней правила переехали из текста в код. Между ассистентом и MCP-сервером стоит taskforge-mcp-proxy — stdio-прокси на Python, который перехватывает каждый вызов записи и до сервера проверяет его по правилам из rules.json.
Режимов два. error — вызов не уходит, ИИ получает «Нарушено правило N (имя): … Исправь: …», исправляет и повторяет. fix — прокси исправляет сам и пишет в ответ «прокси исправил: …». Режима warn нет сознательно: предупреждения ИИ читают так же, как я читаю лицензионные соглашения.
- Связи обязательны. Задача без связей запрещена: нужна родительская задача, вики-ссылка в теле или зависимость. Исключение — тег
rootи пометка «корневая задача проекта». Задача, ни с чем не связанная, — это потерянная задача. - Без опасных символов в заголовке. Никаких
/ \ : * ? " < > | # ^ [ ], иначе ломаются имена файлов и вики-ссылки. - Задача с тегом
agentдолжна иметь время вscheduledи тело не короче 80 символов. Тело — это инструкция, которую ассистент выполнит, когда проснётся, и «сделать» за инструкцию не считается. - У задачи со временем есть напоминание (fix).
add_taskне умеет писать напоминания, поэтому прокси дописывает их отдельным вызовом после записи. - При закрытии
onCompletion: archive(fix). В TurboQuant задача-замер не закроется без заполненныхresult,measured_atиrun_dir. blockedиdeferredтребуют причины и связи. Нужна строкаПричина: …илиЖдёт: …и ссылка на то, чего задача ждёт. Если она ждёт меня, то ссылка ведёт на задачу «Решение Романа — …».- Удаление под замком. Удалять можно только тестовые задачи или задачи с тегом
delete-ok, пачками не больше 25. - Только своё пространство. Создавать задачи в чужом проекте или в несинхронизируемой папке нельзя.
Кусочек rules.json, чтобы было понятно, насколько это просто устроено:
"blocked_needs_reason": {
"enabled": true,
"mode": "error",
"statuses": ["blocked", "deferred"],
"reason_regex": "(?im)^[\\s>*_-]*(Причина|Ждёт|Ждет)[*_]*\\s*:[*_\\s]*\\S",
"require_blocker": true,
"cross_space_prop": "blocked_by_ref"
}
Файл перечитывается по mtime, перезапуск не нужен. Если файл битый, остаётся прежний рабочий конфиг, а ошибка уходит в журнал. Если сломалась сама проверка, вызов уходит как есть, чтобы прокси никогда не стал причиной, по которой трекер не работает. Все решения прокси пишутся в validation.log: дата, vault, инструмент, правило, block или fix. К прокси есть тесты на свежей копии Admin-vault’а, боевое хранилище они не трогают.
Прокси ловит только записи через MCP. Телефон, Obsidian и Claude на ноутбуке (у него свой MCP без прокси) пишут мимо него. Поэтому раз в сутки ночью validate_vault.py проходит по файлам всех хранилищ с теми же правилами и присылает Grok Bot отчёт. В первый же прогон он нашёл больше сотни нарушений в старых задачах; их разобрали за день. Сейчас в типичном отчёте несколько строк.
Шаг 3. Syncthing: телефон, ноутбук, бокс
Синхронизацию делает Syncthing. Это шесть папок: пять проектов и общие настройки TaskForge (dialect.json, spaces.json), без которых MCP не понимает, где у проекта папки. Режимы такие:
- бокс и телефон —
send-receiveдля всех папок; - ноутбук —
send-receiveдля проектов, где работает Claude, иreceive-onlyдля admin: в задачи Admin сессии Claude не пишут; - версии старых файлов складываются в
.stversions/.
Бокс — это общая машина, на которой живут ассистенты Grok Bot. Он иногда перезагружается и обновляется, и при этом теряет часть домашней папки. Поэтому всё, что должно пережить ребут, лежит в /workspace, а поднимает это идемпотентный скрипт:
#!/bin/bash
# box-ensure.sh — восстанавливает то, что бокс теряет при сбросе, и перезапускает фоновые службы.
# 1) taskforge CLI: восстановить из копии, если npm-установка пропала
if [ ! -x ~/.local/lib/node_modules/taskforge-md/bin/taskforge.js ]; then
cp -a /workspace/agent-tools/taskforge-md-copy/. ~/.local/lib/node_modules/taskforge-md/
echo "restored taskforge-md"
fi
# 2) Syncthing: состояние в /workspace/syncthing-state (--home), ключи зеркалируются в бэкап
/workspace/agent-tools/syncthing/syncthing-ensure
# 3) цикл триггеров задач
bash /workspace/agent-tools/task-trigger/tt-start.sh
Ключи и конфиг Syncthing (key.pem, cert.pem, config.xml) syncthing-ensure зеркалирует в бэкап и возвращает обратно, если каталог состояния пропал. Это правило написано кровью ИИ агентов :)
Сверху работает рутина «Сторож Syncthing и цикла задач». Сначала она запускалась каждый час, сейчас реже, раз в четыре часа: токены не бесплатные. Сторож запускает box-ensure.sh (если в выводе есть restored или started, значит, бокс перезагружался, и я получаю одну строку). Через REST проверяет, что папок ровно столько, сколько должно быть, что все они idle с need=0 и что телефон и ноутбук подключены. Ищет новые *.sync-conflict-* и проверяет, что цикл триггеров жив. Если всё в порядке, сторож молчит. Пишет мне только при настоящей проблеме.
Шаг 4. Задачи, которые будят ассистента
Задача с тегом agent и временем в scheduled — это будильник для ИИ. В её теле лежит инструкция. Когда наступает время, ассистент просыпается и выполняет её.
Работает это так. На боксе крутится один цикл tt-loop.py, который раз в минуту через taskforge CLI опрашивает все хранилища из vaults.txt. Событий три:
| kind | Когда | Что происходит с задачей |
|---|---|---|
scheduled |
тег agent, scheduled ≤ сейчас, задача не в работе и не закрыта |
разовая переходит в in_progress, повторяющаяся сдвигается на следующее вхождение (пропущенные склеиваются в одно пробуждение) |
reminder |
наступило напоминание TaskNotes (PT0M, -PT1H, абсолютное время) |
ничего: статус не меняется |
precheck |
за 90 минут до дедлайна ЛЮБОЙ открытой задачи со временем | ничего: ассистент только проверяет, стоит ли на задаче будильник или напоминание, и чинит, если нет |
Последний тип события — страховка от меня. Если я поставил задачу «к 15:00», но забыл тег или напоминание, ассистент заметит это за полтора часа, а не после того, как дедлайн прошёл.
Изначально цикл слал вебхуки, и ассистент просыпался мгновенно. Потом от вебхуков отказались (кто то ддосит Grok Bot), и теперь доставка выглядит так:
{
"delivery": "log",
"default": "admin",
"rules": [
{"vault": "liberec", "recipient": "admin"},
{"tag": "agent-lberec", "recipient": "admin"}
],
"vault_options": {"liberec": {"reminders_any_tag": true}}
}
Цикл пишет строки [EVENT] в свой журнал, а Admin раз в 10 минут запускает одну рутину «Проверка писем Claude и задач TaskForge». Сначала идёт дешёвая предпроверка: маленький скрипт на боксе смотрит события, а такой же скрипт на ноутбуке смотрит почту. Если ответ NONE, рутина сразу заканчивается и почти не тратит токенов. Если что-то есть, Admin обрабатывает своё, а чужое пересылает адресату: например, события бытового проекта уходят его ассистенту. Остальные боты собственных опросов не держат. Опрашивает один, и платим за один.
Выполнив разовую задачу, ассистент закрывает её. Если работа длинная, он оставляет задачу в in_progress, пишет в тело, что запущено и где лог, и ставит себе новую задачу-будильник «проверить в 06:45». Так у меня в трекере появились задачи вида «Admin — будильник 14.10 06:45, проверка приёмки шага 2».
Ночной самотест. Каждый день в 23:50 selftest.py создаёт в Admin-vault’е задачу admin-selftest-<дата> с тегом agent и временем «через две минуты». Он ждёт, пока цикл её заметит, отправит событие и переведёт задачу в работу, а потом закрывает её. Любой сбой дописывается в selftest-fail.txt. Нет файла — нет проблем; есть файл — Grok Bot узнает. Самотест честно доказывает только то, что цикл жив и события уходят. То, что ассистент проснулся и что-то сделал, проверяют уже по результатам в трекере.
Шаг 5. Сессии Claude: сначала задача, потом код
Проектную работу делает Claude Code на ноутбуке. Одна длинная сессия на весь проект быстро переполняет контекст, начинает забывать начало и дорого стоит. Поэтому работа нарезана на группы задач, и каждая группа получает свою свежую сессию: mon-g0, tq-g1 и так далее. Открывает и закрывает их Admin через interconnect:
# открыть сессию под группу, связав её с задачей-хабом группы
python3 interconnect.py open tq-g5 ~/projects/turboquant --task turboquant:<id-хаба>
# кто чем занят: состояние, время в нём, непрочитанные письма, связанная задача
python3 interconnect.py sessions
python3 interconnect.py watch --idle-min 60 # сторож: печатает только проблемы
# письмо в ящик сессии, затем «толчок» в терминал, если она ждёт ввода
python3 interconnect.py send --from admin --to tq-g5 "Start: hub task <id>, rules in the start letter"
python3 interconnect.py nudge tq-g5
interconnect — это файловые почтовые ящики с flock плюс управление tmux-сессиями. Скрипт сам ничего не решает и ничего не нажимает. Он сообщает состояние (РАБОТАЕТ, ЖДЁТ ВВОДА, ЖДЁТ ПОДТВЕРЖДЕНИЯ, ЛИМИТ, УПАЛА), а решает Grok Bot Admin. Каждые 15 минут сторож запускает watch. Пустой вывод значит, что всё хорошо. «ЖДЁТ ВВОДА + непрочитанные» значит nudge. Меню и подтверждения разбираются по правилам, а всё, что касается удаления или публикации, решаю я.
Правила для сессий родились из конкретных неприятностей, и каждое теперь вписывается в стартовое письмо каждой сессии:
- Сначала задача, потом реализация. Перед тем как делать шаг, сессия заводит на него задачу в трекере через MCP. Потом делает шаг и записывает результат в эту задачу. Так в трекере остаётся полный путь разработки, а не только итог. Отсюда и тысяча задач в одном проекте.
- Вопросы только письмом. Сессия, которая молча ждёт ответа в терминале, считается ошибкой. Любой вопрос, решение или блокировку, включая запросы подтверждения от самого Claude Code, сессия отправляет письмом в ящик
adminи продолжает другую работу. - Результаты перепроверяет тот, кто их получил. Если замер выглядит подозрительно, Admin сам в логи не лезет, а поручает проверку сессии и обсуждает с ней вывод до согласия. Ко мне приходят только вопросы, которые остались неясными, по одному, с вариантами и рекомендацией.
- Знания попадают в трекер до закрытия. Перед закрытием сессия сдаёт handoff — документ во вложениях проекта: что сделано, что прервано, как продолжить, что предлагается дальше. Каждая новая идея, находка, проблема и новая работа в handoff должна иметь id задачи в трекере. Admin сверяет handoff с трекером построчно, по таблице «пункт → id». Пункт без id возвращается сессии.
- Закрыть без сверки нельзя технически.
closeбез флага--reconciledоткажет, а пока сессия работает, тоже откажет:
$ python3 interconnect.py close cs-test
close: сверка не отмечена (задача: admin:...). Сначала handoff + задачи/хабы через MCP
+ сверка Admin + «сверка ок», затем повторить с --reconciled
Порядок всегда одинаковый: handoff → сверка трекера (задачи, хабы, дубли) → письмо «сверка ок» → close --reconciled → снимок экрана в logs/closed/, путь к нему записывается в задачу. Логи сессий не удаляются никогда.
Мне нравится, как это смотрится с телефона. Я открываю TaskForge и вижу хаб группы, его подзадачи с результатами и handoff со ссылками. Если хочется, через remote control Claude подглядываю в саму сессию. Решения, которые ждут меня, лежат отдельными задачами «Решение пользователя — …», и от них по depends_on зависят задачи, которые без меня не двинутся.
Шаг 6. Правила, без которых всё это не живёт
Часть правил стоит в прокси, а часть — это договорённости, которые записаны в навыках ассистентов и проверяются ночью:
- Любое удаление — через карантин. Ничего не удаляется напрямую. Сначала объекты переносятся в
quarantine/<дата>-<задача>/с манифестом (путь, размер, sha256). Git-ветки сначала упаковываются вgit bundle, бандл проверяетсяgit bundle verify, его sha256 записывается в задачу. Затем проверяется, что ничего нужного не ушло. Окончательное удаление идёт отдельным шагом, только после моего «ок», и записывается в задачу. Это касается даже чисток, которые я сам одобрил. - Дубли не удаляются, а отменяются со ссылкой. Дубль получает строку «Дубль: [[основная задача]]» и статус
cancelled. История остаётся, ссылки на дубль продолжают работать, а при следующей миграции понятно, откуда что взялось. - Заблокированная задача ссылается на то, чего ждёт. «Ждёт: ответа» без ссылки не считается. Если задача ждёт меня, то её блокирует задача-решение, и я вижу полный список ожидающих.
- Документы переносятся в трекер, а не копируются. Отчёт, лог, план или выгрузку кладут в
attachments/проекта и ссылаются на них из задачи. После проверки sha256 и ссылки оригинал удаляется (тоже через карантин). Документ без задачи значит потерянную задачу. Модели, бинарники, секреты и файлы больше ~50 МБ в трекер не попадают, в задаче записывается только путь к ним. - Задачи читаем раньше документов. Чтобы экономить токены, ассистент сначала читает задачи (там лежат свойства и выжимки), идёт по ссылкам на другие задачи и только при нехватке данных открывает вложения. Тяжёлое чтение он поручает исполнителю и просит прислать только выводы.
Грабли
Места, где ИИ потратил время (а пару раз чуть не потерял данные), чтобы вы не потратили.
- Syncthing разрешает конфликты молча. Если две стороны поправили один файл, Syncthing оставит под нормальным именем более новую по mtime версию, а старую положит рядом как
<задача>.sync-conflict-<ДАТА>-<ВРЕМЯ>-<УСТРОЙСТВО>.md. Уведомлений не. - Бокс потерял ключи Syncthing. Однажды при обновлении (комп облачный Grok Bot) каталог состояния Syncthing на боксе пересоздался.
- Телефон завис на 95% из-за длины имени файла. Конфликтная копия задачи с длинным русским названием получила имя в 251 байт.
- Ребут воскресил двести закрытых задач. После перезагрузки бокса около двухсот уже закрытых задач во всех пяти проектах вернулись в активные папки как старые копии, а их актуальные закрытые версии остались в
Archive/. Syncthing сделит за версиями, боты разобрали все сами. - ИИ сочиняет формат по памяти. До MCP-only ассистент однажды «аккуратно поправил» несколько задач руками, по аналогии с соседними. Приложение на телефоне потом показывало их без статуса.
- Новые задачи уезжали в несинхронизируемую папку. По умолчанию TaskForge кладёт новые задачи в
TaskNotes/Tasks, а эта папка не синхронизируется. Задачи создавались и исчезали для всех, кроме того, кто их создал. На боксе это лечит прокси (подставляет пространство и запрещаетTaskNotes/Tasksправилом 8), на ноутбуке — обёртка с подменойdialect.json. Перенести задачу оттуда на ноутбуке нельзя:move_taskпадает сEXDEVчерез bind mount. Поэтому о таких задачах ИИ сообщает, а не чинит их сам. - Сессия Claude молча ждёт. Claude Code любит спросить «Do you want to proceed?» и ждать часами. Сессия при этом выглядит живой, а работа стоит. Отсюда правило «вопросы только письмом», сторож
watchи проверка, чтоnudgeдействительно нажал Enter (до трёх нажатий, затем «Enter НЕ принят» и разбор по экрану). После сброса лимита Claude сам работу не продолжает, его нужно толкнуть этим занимается Grok Bot. - Знания умирают вместе с сессией. Первые сессии закрывались с хорошим handoff, но половина находок в нём не превратилась в задачи и через день была забыта. Теперь действует гейт: каждый пункт handoff сопоставлен с id в трекере, иначе
close --reconciledне выполняется. - Вебхуки оказались лишними. Мгновенное пробуждение по вебхуку выглядело красиво, пока вебхук не начал отвечать HTTP 400 на каждое письмо так как Grok ддосят.
Что в итоге
- Трекер — это папка с файлами. Пять проектов, одна задача = один Markdown-файл. Читается глазами, Obsidian’ом, grep’ом и переживёт любое приложение. Ни одного облака по дороге.
- Телефон — главный пульт. Я вижу всё, что делают ИИ: каждый шаг, каждый результат, каждое решение, которое ждёт меня, с зависимостями и ссылками на документы.
- ИИ работают через инструменты, а не руками. MCP с валидирующим прокси на боксе, CLI/MCP на ноутбуке, восемь правил на каждой записи и ночная проверка всех файлов.
- Задачи будят ассистента. Тег
agentи время превращают задачу в будильник или рутину. Precheck страхует от забытых напоминаний, ночной самотест подтверждает, что цикл жив. - Сессии Claude не уносят знания с собой. Задача на каждый шаг до реализации, handoff со сверкой по id, закрытие только после «сверка ок».
- Ничего не удаляется сразу. Карантин с манифестом, дубли отменяются со ссылкой, конфликты Syncthing разбираются вручную, а не «новее значит правильнее».
- Всё поднимается после ребута само, а я узнаю об этом одной строкой. Ребут 14.10 правда показал, что «поднялось» и «осталось как было» — разные вещи, и разбор воскресших задач ещё впереди.
Рутину — скрипты, прокси, валидацию, сторожей, разбор конфликтов, сверку handoff, даже большую часть этих правил в виде текста — делали ИИ. Решения «что удаляем, что считаем дублем, когда закрываем сессию, какое правило становится жёстким» оставались за мной. Каждое такое решение лежит в трекере отдельной задачей с датой. Забавно, что половина правил выше появилась как реакция на то, что ИИ сделал что-то очень уверенно и очень не так. Трекер, в котором работают ИИ, в итоге оказался не про задачи, а про то, как сделать ошибку дешёвой и заметной.
P.S. Самым полезным правилом оказалось не самое умное, а самое занудное: «сначала заведи задачу на шаг, потом делай». Сессии пишут тысячу задач, но теперь на вопрос «а почему мы так решили неделю назад» есть ответ в трекере, а не в закрытой сессии.