Агент v13: журнал изменений Jira в refresh (#39) #40

Merged
aep merged 7 commits from feat/39-change-history into main 2026-10-22 10:05:46 +03:00
Owner

Closes #39. Парный PR хаба: aep/jira-hub#70 (feat/70-change-history) — контракт и спека там (openspec/changes/change-history/).

Что сделано

  • Агент v13: после отправки состояния refresh читает changelog Jira по параметру history: стартовая выборка history.jql (первой, журнал целиком) и задачи этого прогона с updated >= history.since (search key in (...), expand=changelog, по 100); неполный журнал дочитывается GET /issue?expand=changelog, иначе ключ в incomplete; id custom-поля без fieldId — по имени из GET /field (один раз за refresh).
  • Отправка POST /agent/history пачками по 500; итог result.history = {issues, changes, incomplete, error?, backfill_error?}; ответ не 2xx Jira/хаба не роняет refresh, обрыв связи — как раньше.
  • Решения агента: openspec/changes/agent-v13-change-history/design.md; план: docs/superpowers/plans/2026-10-22-change-history-agent.md.

Проверка

  • /usr/bin/python3 -W error::ResourceWarning -m unittest discover -s tests -t . — 305 OK (Python 3.9.6).

Выкатка

После merge (и выкатки хаба): uv run --project ../jira-hub jira-hub agent publish src/agent.py из основного checkout на main; agent_status → «обновление: ok v12 → v13». min_agent_version не поднимать. Затем живая проверка (design хаба, Migration Plan п. 3): стартовая загрузка, отсутствие лишних вызовов при отсутствии изменений, полнота журнала банковской Jira и наличие fieldId.

Rulings I made

  • R-1 (design #17) — шаги миграции v4→v5 добавляют колонку, только если её нет (_add_column): базы v1/v2 получают issue_comment из SCHEMA уже с created_at. Цена ошибки: нет.
  • R-2 (design #18) — прежний тест формата sync_log переписан на строку с «, журнал: нет» (спека mcp). Цена ошибки: нет.
  • R-3 (агент) — ошибка GET /field / дочитывания GET /issue относится к прерванной части журнала: регулярная → history.error, стартовая → backfill_error. Цена: стартовая с упавшим GET /field не держит отметку.
  • R-4 (агент) — ошибка одной части журнала не отменяет другую и отправку уже прочитанного. Цена: при error отметка не сдвинется, повтор дочитает.
  • R-5 (агент) — неразбираемый history.since → history.error, refresh остаётся done. Цена: нет.
  • R-6 (агент) — недоступный хаб на /agent/history в тестах — FakeHub.reject_history = "drop". Цена: нет.
  • R-7 (design #19, по I-1) — стартовая часть журнала первой, журнал целиком; регулярная не запрашивает уже прочитанные; ключ «прочитан» только после разбора. Цена: при сбое стартовой на задаче регулярная добирает только записи после since.
  • R-8 (design #20, по M-1/M-2) — время за краем диапазона datetime → None; GET /changes — 422 на время без смещения; MCP changes считает такое время местным. Цена: API без смещения теперь 422.
  • Final: M-1 и M-2 подняты из Minor до Important по эффекту (хаб не стартует / окно ленты молча сдвигается на 3 часа).

Findings

Маркер Суть Статус
I-1 агент: задача в обеих выборках (since+jql) теряла старую историю fixed faed8b9
M-1 OverflowError в jira_utc fixed c6a5ef1
M-2 время без смещения молча как UTC fixed c6a5ef1
M-3 агент: неразбираемый created в режиме since отбрасывается без лога deferred
M-4 агент: неожиданная форма ответа Jira на шаге журнала → refresh failed deferred
M-5 хаб: README без changes, POST /agent/history, GET /changes, history_at deferred
M-6 рулинги не в design.md fixed 479bb66 / 4ed011b
M-7 агент: O(n²) отбор изменившихся fixed faed8b9

🤖 Generated with Claude Code

Closes #39. Парный PR хаба: aep/jira-hub#70 (feat/70-change-history) — контракт и спека там (`openspec/changes/change-history/`). ## Что сделано - Агент v13: после отправки состояния `refresh` читает changelog Jira по параметру `history`: стартовая выборка `history.jql` (первой, журнал целиком) и задачи этого прогона с `updated >= history.since` (`search key in (...)`, `expand=changelog`, по 100); неполный журнал дочитывается `GET /issue?expand=changelog`, иначе ключ в `incomplete`; id custom-поля без `fieldId` — по имени из `GET /field` (один раз за refresh). - Отправка `POST /agent/history` пачками по 500; итог `result.history = {issues, changes, incomplete, error?, backfill_error?}`; ответ не 2xx Jira/хаба не роняет `refresh`, обрыв связи — как раньше. - Решения агента: `openspec/changes/agent-v13-change-history/design.md`; план: `docs/superpowers/plans/2026-10-22-change-history-agent.md`. ## Проверка - `/usr/bin/python3 -W error::ResourceWarning -m unittest discover -s tests -t .` — 305 OK (Python 3.9.6). ## Выкатка После merge (и выкатки хаба): `uv run --project ../jira-hub jira-hub agent publish src/agent.py` из основного checkout на main; `agent_status` → «обновление: ok v12 → v13». `min_agent_version` не поднимать. Затем живая проверка (design хаба, Migration Plan п. 3): стартовая загрузка, отсутствие лишних вызовов при отсутствии изменений, полнота журнала банковской Jira и наличие `fieldId`. ## Rulings I made - R-1 (design #17) — шаги миграции v4→v5 добавляют колонку, только если её нет (`_add_column`): базы v1/v2 получают `issue_comment` из SCHEMA уже с `created_at`. Цена ошибки: нет. - R-2 (design #18) — прежний тест формата `sync_log` переписан на строку с «, журнал: нет» (спека mcp). Цена ошибки: нет. - R-3 (агент) — ошибка `GET /field` / дочитывания `GET /issue` относится к прерванной части журнала: регулярная → `history.error`, стартовая → `backfill_error`. Цена: стартовая с упавшим `GET /field` не держит отметку. - R-4 (агент) — ошибка одной части журнала не отменяет другую и отправку уже прочитанного. Цена: при `error` отметка не сдвинется, повтор дочитает. - R-5 (агент) — неразбираемый `history.since` → `history.error`, `refresh` остаётся `done`. Цена: нет. - R-6 (агент) — недоступный хаб на `/agent/history` в тестах — `FakeHub.reject_history = "drop"`. Цена: нет. - R-7 (design #19, по I-1) — стартовая часть журнала первой, журнал целиком; регулярная не запрашивает уже прочитанные; ключ «прочитан» только после разбора. Цена: при сбое стартовой на задаче регулярная добирает только записи после `since`. - R-8 (design #20, по M-1/M-2) — время за краем диапазона datetime → `None`; `GET /changes` — 422 на время без смещения; MCP `changes` считает такое время местным. Цена: API без смещения теперь 422. - Final: M-1 и M-2 подняты из Minor до Important по эффекту (хаб не стартует / окно ленты молча сдвигается на 3 часа). ## Findings | Маркер | Суть | Статус | |---|---|---| | I-1 | агент: задача в обеих выборках (`since`+`jql`) теряла старую историю | fixed faed8b9 | | M-1 | `OverflowError` в `jira_utc` | fixed c6a5ef1 | | M-2 | время без смещения молча как UTC | fixed c6a5ef1 | | M-3 | агент: неразбираемый `created` в режиме `since` отбрасывается без лога | deferred | | M-4 | агент: неожиданная форма ответа Jira на шаге журнала → `refresh` failed | deferred | | M-5 | хаб: README без `changes`, `POST /agent/history`, `GET /changes`, `history_at` | deferred | | M-6 | рулинги не в design.md | fixed 479bb66 / 4ed011b | | M-7 | агент: O(n²) отбор изменившихся | fixed faed8b9 | 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 7 commits 2026-10-22 09:54:38 +03:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep merged commit 4e07de32ed into main 2026-10-22 10:05:46 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: aep/jira-agent#40
No description provided.