92 lines
10 KiB
Markdown
92 lines
10 KiB
Markdown
## Why
|
||
|
||
Мост в ежедневной работе с 13.10.2026; пакеты A (`bridge-reliability`, #9) и B (проверки на живой Jira) закрыты. Осталось
|
||
три follow-up issue в каждом репозитории (hub#4, #8, #12; agent#4, #8, #12). Пакет D (разбор хвоста hub#4/agent#4,
|
||
14.10.2026) разделил их на «в C», «отклонить», «на потом». Этот change — пакет C: мелкие исправления, приведение спек
|
||
к коду и гигиена, одним change на оба репозитория. Новых возможностей нет.
|
||
|
||
Что чинится по существу:
|
||
- **M-7 (hub#4)** — каталог данных хаба `0755`, база `0644`, а в базе токены: читаемы любым локальным пользователем.
|
||
- **M-3 (hub#4, PR #2)** — `rename_note` при переносе `new:N` → ключ удаляет заметку, уже стоящую под настоящим ключом.
|
||
- **T2.3 (agent#4)** — `prune` перезаписывает журнал без блокировки: запись `finished`, добавленная работающим агентом,
|
||
теряется (потерянный отчёт).
|
||
- **M-4 (hub#12)** — поздний `done` с ключом по `ensure_issue`, ставшей `failed` по пределу выдач, отбрасывается: заметка
|
||
`new:N` не переезжает; у `refresh`, ставшего `failed` по пределу, `sync_run.finished_at` пуст.
|
||
- **M-5 (hub#12)** — повторное выполнение `refresh` после довыдачи удваивает счётчики `sync_run`.
|
||
- **M-12 (hub#4)** — полный прогон, вернувший 0 задач, помечает всё зеркало соседями.
|
||
- **T5.6 (hub#4)** — отменённый пакет с частью выполненных команд показывается «завершён».
|
||
- **M-3, M-4 (hub#8)** — реле: `HTTPException` от своего HTTP не превращается в 502; `work/` чистится при каждой
|
||
повторной подготовке, а не только при старте.
|
||
- **M-2 (hub#12)** — параллельные `connect` к базе старой версии делают по копии на соединение.
|
||
- **M-3 (hub#12)** — нестроковый `summary` в `ensure_issue` даёт 500 вместо 422.
|
||
- **M-2 (agent#8)** — ответ папки с неверными типами `status`/`body` роняет агента.
|
||
- **M-6 (agent#12)** — время последней записи журнала в будущем отключает паузу темпа.
|
||
- **M-7 (agent#12)** — после перезапуска в `claim` уходит время записи журнала как «последний вызов Jira».
|
||
- **T3.9 (agent#4)** — Jira хранит текст, правленный в UI, с `\r\n`; агент сравнивает с `\n` из команды и делает лишний
|
||
`PUT` описания/комментария (проверено на живой Jira 13.10.2026: 71 из 180 задач).
|
||
|
||
Решения владельца 14.10.2026 (разбор D и brainstorming):
|
||
- состав пакета C — по таблице разбора D (комментарии hub#4 #3323, agent#4 #3326), плюс M-12 и подсказка про `labels`;
|
||
- T-n без сохранившегося текста ревью — отклонены пачкой;
|
||
- живая проверка потери отчёта, довыдачи и force-cancel — отдельно, не в этом change;
|
||
- M-4 (hub#12): поздний отчёт по `failed` по пределу выдач — как по отменённой (ключ в результат, заметка переезжает,
|
||
статус остаётся `failed`); `refresh`, ставший `failed` по пределу, получает `sync_run.finished_at`;
|
||
- M-7 (agent#12): в `claim` уходит только время настоящего вызова Jira; оценка из журнала — только для паузы;
|
||
- CRLF: агент сравнивает описание и тело комментария после замены `\r\n` на `\n`, отправляет как есть; хаб не меняется.
|
||
|
||
## What Changes
|
||
|
||
- **jira-hub**:
|
||
- права `0700` на каталог данных и `backups/` (при создании и при старте);
|
||
- `rename_note` сливает заметки: поле под настоящим ключом сохраняется, если у временной заметки оно пустое;
|
||
- статус пакета `cancelled`, если пакет отменён и все его команды в терминальных статусах;
|
||
- `report_result` обрезает `error` до 1500 символов;
|
||
- поздний отчёт `done` с ключом по `ensure_issue` в `failed` без результата — как по `cancelled`; при переводе `refresh`
|
||
в `failed` по пределу выдач — `sync_run.finished_at`;
|
||
- довыдача `refresh` обнуляет `issues_count`/`links_count` его `sync_run`;
|
||
- полный прогон с `issues_count = 0` не помечает задачи соседями;
|
||
- `commands.validate`: строковые параметры проверяются на тип (422);
|
||
- миграция: копия перед миграцией и сама миграция — под одной блокировкой записи, копия одна;
|
||
- реле: `http.client.HTTPException` → 502; `work/` чистится только при старте реле; строка лога при повторной
|
||
подготовке не говорит «перезапуск»;
|
||
- ответ `POST /batches/{id}/cancel` и MCP `batch_cancel` сообщают о команде пакета, уже взятой агентом;
|
||
- MCP `batch_create`: в описании инструмента — передавать базовые метки (`labels`) в `ensure_issue`;
|
||
- тесты: `serve --host <IP>` для реле, переименование `test_fresh_definer_still_blocks_queue`, сквозной тест
|
||
«база v1 → миграция → довыдача 1 → 2»;
|
||
- `.wt/` в `.gitignore`; `ARCHITECTURE.md` — реле и `relay_dir`.
|
||
- **jira-agent** (версия 4):
|
||
- сравнение описания и тела комментария без различия `\r\n`/`\n`;
|
||
- время журнала в будущем — принимается за «сейчас» (полная пауза);
|
||
- в `claim` — только время настоящего вызова Jira в этом процессе;
|
||
- ответ папки с неверными типами `status`/`body` — `ConnectionError` (как нечитаемый JSON);
|
||
- `prune` берёт блокировку журнала и отказывает при работающем агенте; README;
|
||
- лог «хаб: хаб не ответил…» без повтора слова.
|
||
- Спеки: `hub-api`, `data-model`, `commands`, `agent`, `mcp`, `migration` — MODIFIED. Кроме исправлений, спеки
|
||
приводятся к коду (разбор D): нет настройки `sprint_names`; коды ответов 413/500/502 и 501 на прочие методы;
|
||
`page`/`last_page` информационные; `GET /issues` — поля зеркала; автообновление — от последнего `sync_run`;
|
||
MCP `refresh` — id пакета; `new:<строка>` — только для `new_tasks.csv`. Раздел `## Purpose` всех шести спек
|
||
заполняется (сейчас — заглушка `TBD`, из-за неё падает `openspec validate --specs --strict`).
|
||
|
||
## Non-goals
|
||
|
||
- Живые проверки потери отчёта, довыдачи, force-cancel и `ensure_link` (agent#12 O-1) — отдельно, на тестовой задаче.
|
||
- «На потом» из разбора D: ResourceWarning в тестах хаба (M-9/O-4), пробелы тестов (M-10 хаба), точность фейков агента
|
||
(M-10 агента).
|
||
- Отклонённые в разборе D пункты (M-4, M-8/T6.12, T5.4, T5.11, T6.5, T6.6, T9.1, T1.1, M-6, M-11 хаба; FM-1…FM-3, O-2,
|
||
T1.9, N-3, T2.7, T3.2, T3.3, T4.7, T4.11, T5.2, T7.6, «Task 2 minor» агента; T-n без текста).
|
||
- Автодобавление базовых меток хабом или агентом (T3.7): только подсказка в описании инструмента.
|
||
- MCP-инструмент отмены отдельной команды: `batch_cancel` лишь подсказывает про `force`.
|
||
- Подъём `min_agent_version` до 4.
|
||
|
||
## Impact
|
||
|
||
- `jira-hub`: `paths.py`, `db.py` (миграция под блокировкой, права), `mirror.py` (`rename_note`), `queue.py` (`_status_of`,
|
||
`report_result`, `_redeliver`, `claim`, `cancel_batch`), `commands.py` (`validate`), `relay.py`, `api.py` (ответ отмены
|
||
пакета), `mcp_server.py` (`batch_cancel`, `batch_create`), тесты, `.gitignore`, `ARCHITECTURE.md`.
|
||
- `jira-agent`: `src/agent.py` (`do_ensure_fields`, `do_ensure_comment`, `restore_pace`, `JiraClient.last_call_iso`,
|
||
`FolderTransport`, `cmd prune`, лог), `README.md`, тесты, `.gitignore`; версия 4.
|
||
- Контракт хаб ↔ агент: тела запросов не меняются; ответ отмены пакета получает поле `still_claimed`.
|
||
- Выкатка: хаб — `git pull` + перезапуск launchd (схема не меняется), проверить права каталога; агент v4 — через
|
||
общую папку, как v3.
|
||
- Issues: aep/jira-hub#13, aep/jira-agent#15; закрывают hub#8, hub#12, agent#8, agent#12, а hub#4/agent#4 — кроме «на потом».
|