I-1, I-2 финального ревью: старые MCP-сессии возвращали status_labels/transitions_map после миграции; окно до kickstart описано для v8. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
13 KiB
Context
Основа — main после sdlc-rename (#97) и web-modules (#98), 5a21825. Схема базы — v7 (core/db.py,
SCHEMA_VERSION = 7). Issue #104, ветка feat/104-fact-status-removal.
Где живёт статус по факту (разведка 24.10.2026):
- база:
issue_note.fact_status(modules/jira/schema.py);mirror.NOTE_FIELDS, фильтрfact_statusвmirror.list_issues, колонка в выборкахlist_issuesиboard_snapshot(modules/jira/mirror.py); - API:
ISSUE_FILTERS(modules/jira/api.py);PUT /issues/{key}/noteпринимает поле черезNOTE_FIELDS; - MCP:
issues(параметр и колонка таблицы),notes_set(параметр),issue(строка заметок) —modules/jira/mcp.py; - настройки:
status_labels,transitions_mapвDEFAULTSиAGENT_KEYS(modules/jira/settings.py), перенос из конфига вinit --config(там же); - импорт: колонка «Статус по факту» в
tasks.csv/new_tasks.csv(modules/jira/importer.py); - веб: типов с
fact_statusуже нет (#57); остались фикстуры (board/__fixtures__/hub-basic.board.json,settings.json), тест-страж терминов (boundary.test.ts), тест «параметр из адреса не уходит в запрос» (IssuesPage.test.tsx) и сидер тестового хабаweb/scripts/seed-hub.py— он пишетfact_statusв заметки черезPUT /issues/{key}/noteи после change получит 422; - тесты хаба и эталоны:
tests/fixtures/baseline/{mcp_tools,settings,schema}.expected.json,test_db,test_mirror,test_api,test_mcp,test_importer,test_settings,test_e2e_hub,test_cli,test_queue,test_agents;tests/fixtures/{settings_v6,schema_v6,config.example}.json— входы миграционных тестов, исторические.
jira-agent (../jira-agent/src/agent.py) ни status_labels, ни transitions_map не читает: ensure_status получает
путь статусов в параметре target. Потребители MCP в ~/projects поле не упоминают.
Goals / Non-Goals
Goals: в хабе нет ни поля, ни настроек, ни параметров статуса по факту; живая база v7 мигрирует при старте без ручных шагов; прочие заметки целы.
Non-Goals и Anti-Goals: см. proposal.md.
Decisions
-
Колонка удаляется, а не обнуляется (решение владельца 24.10.2026: «удаляй безвозвратно»). Шаг миграции v7 → v8 —
ALTER TABLE issue_note DROP COLUMN fact_status, только если колонка есть (новая база v8 собирается схемой без неё). Сам шаг живёт в модуле jira (функция вmodules/jira/, ядро вызывает её ленивым импортом изMIGRATIONS[7], как_project_fields_v7вызываетprojects.migrate_v6): термины jira в ядро не попадают (test_core_has_no_jira_terms). SQLite хаба — 3.50 (Python 3.13 от uv),DROP COLUMNподдерживается с 3.35. Копию базы делает общий механизм миграции (backups/<дата>-schema-v7.sqlite), отдельной выгрузки нет. -
Ключи
status_labelsиtransitions_mapудаляются изsettingтой же миграцией и уходят изDEFAULTSиAGENT_KEYS, иначеensure_defaultsсоздаст их снова. Если удалён хотя бы один ключ —settings_version+ 1: набор ключей агента изменился, агент перечитает настройки (на работу агента это не влияет). Строкиsettings_versionможет не быть (база безensure_defaults) — тогда версия не поднимается и не создаётся. -
PUT /issues/{key}/noteсfact_status— 422 «неизвестные поля заметки: fact_status» — общее правилоmirror.set_noteдля полей внеNOTE_FIELDS, отдельного кода нет. -
GET /issues?fact_status=…— параметр игнорируется, как любой неизвестный:h_issuesчитает толькоISSUE_FILTERS. Веб его уже не шлёт, а старые закладки с параметром не ломаются. -
init --configне переноситstatus_labelsиtransitions, даже если они есть в конфиге. -
Импорт пропускает колонку «Статус по факту»; остальные колонки — как раньше.
-
Веб: только тесты, фикстуры и сидер.
seed-hub.pyперестаёт писатьfact_statusв заметки. Изhub-basic.board.jsonиsettings.jsonполе и ключ убираются; golden-эталоны доски (*.expected.json) MUST NOT измениться — доска поле не читает.fact_statusвMODULE_TERMSтеста-стража остаётся: ядро веба по-прежнему не должно его содержать. ТестIssuesPage.test.tsxпро параметр из адреса остаётся (поведение то же). -
Исторические фикстуры (
*_v6.json,config.example.json) не правятся: это входы миграций иinit, на них проверяется, что поле и ключи пропадают. -
Спека
data-model: «текущая — 8», сценарии миграций v1–v5 вместо числа говорят «текущая» — число «6» в них отстало от кода ещё в wiki-module (v7) и ломалось бы при каждой новой версии. -
Документация и тексты в коде правятся вместе с кодом: README (описание
import, строкиGET /issuesиGET /board), docstringmirror.board,mcp.issues,mcp.notes_set, обе строки чтения CSV вimporter.py. Исторические планыdocs/superpowers/plans/*.mdи архивopenspec/changes/archive/не правятся; итоговая проверка —grep -rn "fact_status\|status_labels\|transitions_map\|по факту" src web/src web/scripts README.md ARCHITECTURE.md openspec/specsдаёт только намеренные остатки (стражMODULE_TERMS, тест параметра из адреса, текст спек «статуса по факту нет»). -
Устаревшие ключи настроек объявляет модуль (
Module.settings_obsolete, у jira —status_labels,transitions_map);core.settings.ensure_defaultsудаляет их при каждом вызове,settings_versionне поднимает (агенту ключи не передаются). Ядро имён ключей не знает.
Справка: пути переходов из transitions_map
Значение настройки на живом хабе 24.10.2026 — пути по workflow AURORA (статус Jira, в который переводили задачу,
по виду работы; default — для видов, которых нет в строке; «—» — пути нет). Ключи — статусы по факту, сами пути пригодятся для спринтов/бэклога.
| Статус по факту | default | аналитика / решение / актуализация | организационная |
|---|---|---|---|
| Готово — закрыть | Разработка → Готово к тестированию | Разработка → Готово | Разработка → Готово |
| В работе | Разработка | Ожидает анализа → Анализ | Разработка (default) |
| Ожидает решения владельца/заказчика | Ожидает анализа | Ожидает анализа | Ожидает анализа |
| К актуализации аналитики | Ожидает анализа | Ожидает анализа | Ожидает анализа |
| Ожидание разработки | — | Ожидает анализа | — |
| Частично — переформулировать | — | Ожидает анализа | — |
| Снято | Снято | Снято | Снято |
status_labels сопоставлял статусам по факту служебные метки fact-* (fact-done, fact-partial,
fact-in-progress, fact-decision, fact-docs, fact-open, fact-roadmap, fact-cancelled).
Risks / Trade-offs
- Значения статуса по факту теряются — решение владельца; восстановить можно только из
backups/. - Новый код до kickstart. MCP-сервер и CLI открывают базу сами (
HubClient.from_home()→db.connect+ensure_defaults). Новая сессия Claude,/mcp→ reconnect илиsdlc-hub tokensмеждуgit pullиkickstartмигрируют базу до v8, а хаб на прежнем коде отвечает 500 наGET /issues,GET /board,PUT /issues/{key}/note(нет колонки). Порядок выкатки —git pull→ сразуkickstart(README, ARCHITECTURE.md, раздел о выкатке схемы). - Старый код после kickstart. Долгоживущие MCP-сессии со старым кодом при каждом вызове открывают базу и своим
ensure_defaultsснова вставляютstatus_labels/transitions_map({}); миграция уже прошла и не повторится, а удалить ключ через API нельзя (I-1 финального ревью). Поэтому ключи объявлены устаревшими модулем (Module.settings_obsolete), иensure_defaultsнового кода удаляет их при каждом вызове — при старте хаба и в каждой новой MCP-сессии (design #11). Пока жива старая сессия, ключи могут появляться между её вызовами и вызовами нового кода; агенту они не уходят (AGENT_KEYSнового кода). - Сессии MCP со старым кодом до
/mcp→ reconnect показывают параметрfact_status; вызов с ним вернёт пустой фильтр (хаб параметр игнорирует),notes_setс ним — 422.
Decisions made without discussion
- 24.10.2026 — R-1 (design #2):
transitions_mapиstatus_labelsудаляются вместе с полем; пути переходов сохранены в разделе «Справка» этого документа. Обоснование: ключи карты — статусы по факту, читателей нет. Цена ошибки — вернуть настройку из справки одной правкойPUT /settings. - 24.10.2026 — R-2: jira-agent не меняется, design-only change в агенте не заводится (агент ключи не читает). Цена ошибки — отдельный PR в агенте.
- 24.10.2026 — R-3 (design #2):
settings_versionподнимается, если миграция удалила ключ. Цена ошибки — один лишний перечит настроек агентом. - 24.10.2026 — R-4 (design #3, #4): запись поля в заметку — 422, фильтр в
GET /issues— игнорируется. Обоснование: общие правила хаба для неизвестных полей тела и параметров. Цена ошибки — правка одного обработчика. - 24.10.2026 — R-5: M-3, M-4, M-5 из #60 в change не входят и остаются в #60. Цена ошибки — отдельная мелкая задача.
- 24.10.2026 — R-7 (design #11): после I-1 финального ревью — устаревшие ключи удаляет каждый
ensure_defaults, без подъёмаsettings_version. Обоснование: старые MCP-сессии возвращают ключи, а удалить их иначе нечем. Цена ошибки — поле контракта модуля, которое придётся убрать. - 24.10.2026 — R-6 (design #9): в
data-modelисправлено отставание номера версии схемы. Цена ошибки — нет.