agent-ecosystem/docs/team-management/research-tasks.md
iliya e7d9e82ce8 feat(team-management): implement initial Team Management feature with Kanban support
- Added core documentation for the Team Management feature, including iteration goals, implementation plans, and design specifications.
- Introduced new files for team configuration, IPC channels, and UI components for team listing and Kanban board.
- Established a clear definition of done and scope for the first iteration, focusing on visible results and graceful degradation in the UI.
- Documented the messaging and task file formats, ensuring robust communication between team members.
- Implemented a Kanban design with defined states and transitions for task management.
2026-02-17 21:10:15 +02:00

158 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Research: Task-файлы Claude Code
## Формат
**Путь**: `~/.claude/tasks/{teamName}/{id}.json`
```json
{
"id": "48",
"subject": "Rename package in pubspec.yaml",
"description": "Change name: dartdoc to name: dartdoc_vitepress",
"activeForm": "Updating pubspec.yaml",
"owner": "senior-1-rename",
"status": "completed",
"blocks": [],
"blockedBy": [],
"metadata": { "_internal": true }
}
```
### Поля
| Поле | Обязательно | Тип | Описание |
|------|:-----------:|-----|----------|
| `id` | YES | string | Числовой ID в виде строки ("1", "48") |
| `subject` | YES | string | Краткий заголовок задачи |
| `description` | NO | string | Детальное описание |
| `activeForm` | NO | string | Present continuous для спиннера ("Updating...") |
| `owner` | NO | string | Имя агента-владельца |
| `status` | YES | string | pending / in_progress / completed / deleted |
| `blocks` | NO | string[] | ID задач, которые зависят от этой |
| `blockedBy` | NO | string[] | ID задач, от которых зависит эта |
| `metadata` | NO | object | Произвольный объект |
### Статусы
```
pending — задача создана, ждёт исполнителя
in_progress — агент работает над задачей
completed — агент завершил
deleted — задача удалена
```
---
## .highwatermark
**Путь**: `~/.claude/tasks/{teamName}/.highwatermark`
**Содержимое**: число (последний выданный ID)
### Как используется
```
1. TaskCreate → читает .highwatermark (например, "48")
2. Новый ID = 49
3. Создаёт 49.json
4. Записывает "49" в .highwatermark
```
### Риск при внешней записи
Если мы создаём задачу с ID=50, но .highwatermark = 48:
- Следующий TaskCreate создаст 49.json (ОК)
- Ещё один — 50.json → **ПЕРЕЗАПИШЕТ нашу задачу**
**Решение**: Не создавать задачи напрямую. Мы только ЧИТАЕМ задачи и модифицируем status/metadata.
---
## .lock файл
**Путь**: `~/.claude/tasks/{teamName}/.lock`
**Содержимое**: пустой файл (0 байт)
### Поведение
- Обновляется (touch) при обращении к tasks
- Механизм блокировки НЕДОКУМЕНТИРОВАН
- Вероятно используется как advisory lock (наличие = кто-то работает)
### Наш подход
Не трогаем .lock. Он для Claude Code. Мы делаем atomic write (tmp + rename) что безопасно без lock.
---
## Видимость для агентов
| Инструмент | Видит status | Видит metadata | Видит owner | Видит blockedBy |
|------------|:---:|:---:|:---:|:---:|
| TaskList | YES | **NO** | YES | YES |
| TaskGet | YES | YES | YES | YES |
| TaskUpdate | Меняет | Меняет | Меняет | Меняет |
**Следствие**: Агент через TaskList НЕ увидит наш kanbanColumn в metadata. Поэтому хранить kanban-состояние в metadata бессмысленно для агентов, и рискованно (может быть перезаписано).
---
## metadata: merge vs replace
### Проблема
**НЕДОКУМЕНТИРОВАНО.** Неизвестно что происходит при:
```typescript
// Текущее состояние:
{ metadata: { kanbanColumn: "REVIEW", _internal: true } }
// Агент делает TaskUpdate:
TaskUpdate({ metadata: { owner_note: "done" } })
// Результат ???
// MERGE: { kanbanColumn: "REVIEW", _internal: true, owner_note: "done" }
// REPLACE: { owner_note: "done" } ← kanbanColumn ПОТЕРЯНО
```
### Решение
Не полагаемся на metadata. Kanban-состояние храним в собственном файле `kanban-state.json`.
---
## Конкурентный доступ
### Сценарий
```
T=0: App читает task.json: { status: "completed", metadata: {} }
T=1: Agent читает тот же файл: { status: "completed", metadata: {} }
T=5: App пишет: { status: "in_progress", metadata: {} } (Fix)
T=6: Agent пишет: { status: "completed", metadata: { note: "done" } }
→ Наш status: "in_progress" ПОТЕРЯН
```
### Вероятность
**СРЕДНЯЯ** — мы пишем в task только при Fix (status → in_progress). Но агент может одновременно обновлять тот же файл.
### Митигация
1. **Atomic write** (tmp + rename)
2. **Verify after write**: перечитать файл, проверить что status = наш
3. **File watcher**: если status изменился обратно → показать warning в UI
### Что пишем в task-файлы
Минимум — только `status` при Fix:
```typescript
// Читаем текущий task
const task = JSON.parse(fs.readFileSync(taskPath));
// Меняем только status
task.status = 'in_progress';
// Atomic write
const tmp = taskPath + '.tmp.' + process.pid;
fs.writeFileSync(tmp, JSON.stringify(task, null, 2));
fs.renameSync(tmp, taskPath);
```
Всё остальное (kanbanColumn, reviewStatus) — в нашем kanban-state.json.