Andrey Epifancev e34d61a483 spec(sdlc-rename): R-2 в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 11:33:18 +04:00

109 lines
13 KiB
Markdown
Raw 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.

## Context
`main` bb54d0a: схема v7, модули `jira` и `wiki`, агенты jira v14 и wiki v1. Имя `jira-hub` живёт в:
- **коде:** пакет `src/jira_hub/` (≈30 файлов импортируют `jira_hub`), `pyproject.toml` (дистрибутив и скрипт
`jira-hub`), `core/paths.py` (`JIRA_HUB_HOME`, `~/.local/share/jira-hub`), `core/cli.py` (`prog`, модуль MCP по
умолчанию `jira`), `core/mcp.py` (`mcp_json`: серверы `jira-hub`/`jira-hub-<модуль>`), `FastMCP("jira-hub")` и
`FastMCP("jira-hub-wiki")`, подсказки «jira-hub serve», `api.py` (текст «make web в каталоге jira-hub», строка запуска);
- **тестах:** `JIRA_HUB_HOME` в фикстурах, эталон `tests/fixtures/baseline/mcp_wiki_tools.expected.json`, проверки имён
серверов и фрагментов `.mcp.json`, пути `src/jira_hub` в `test_layout`, `test_registry`, `test_web_app`,
`test_wiki_projects`;
- **вебе:** `<title>Хаб Jira</title>`, бренд в `shell/Sidebar.tsx`, ключи `jira-hub-token|sidebar|legend`,
`JIRA_HUB_URL` в `vite.config.ts`, `web/scripts/test-hub.sh`, `package.json` (`jira-hub-web`), подсказка входа;
- **документации:** README (launchd, MCP, выкатка), CLAUDE.md, ARCHITECTURE.md, Makefile, `openspec/specs/` (18
требований в 7 спеках);
- **проектах-потребителях** (не git): `awp-ca` — `.mcp.json`, `enabledMcpjsonServers` в `.claude/settings.local.json`,
`CLAUDE.md`, скилл `building-customer-error-report` (`mcp__jira-hub__*`); `stocks_drrk` — `.mcp.json`,
`enabledMcpjsonServers`;
- **живой установке:** launchd `ru.aepif.jira-hub` (`uv run --project …/jira-bridge/jira-hub jira-hub serve`, лог
`~/Library/Logs/jira-hub.log`), данные `~/.local/share/jira-hub/`, `.mcp.json` в `~/projects/awp-ca` и
`~/projects/stocks_drrk` (серверы `jira-hub`, `jira-hub-wiki`), user scope MCP `jira-hub`, репозиторий Gitea
`aep/jira-hub`, checkout `~/projects/jira-bridge/jira-hub` с worktree в `.wt/`;
- **соседях:** jira-agent и eva-agent упоминают `jira-hub` только в документации, `agent.example.json` и e2e-скрипте
eva-agent (`JIRA_HUB_HOME`, `jira-hub` CLI). Протокол агента имени хаба не содержит: агенты ходят через общую папку.
## Goals / Non-Goals
**Goals:** одно имя `sdlc-hub` в коде, CLI, данных, MCP, вебе и документации; живой хаб переключается одним скриптом
владельца с сухим прогоном; новый код не может молча работать с пустым каталогом данных рядом с живым.
**Non-Goals и Anti-Goals:** см. proposal.md.
## Decisions
1. **Имя — `sdlc-hub`** (решение владельца 23.10.2026). Бренд в вебе — «SDLC Hub».
2. **Псевдонима `jira-hub` нет.** Старые записи MCP и launchd после переключения должны падать явно, а не работать
«почти». Переключение делает скрипт сразу для всех известных потребителей.
3. **MCP-серверы `sdlc-<модуль>`**, модуль в `sdlc-hub mcp` обязателен. Модуль по умолчанию был нужен только ради
неизменных записей `.mcp.json` в hub-modules; при переименовании записи меняются всё равно. Имена инструментов в
Claude станут `mcp__sdlc-jira__*` и `mcp__sdlc-wiki__*`.
4. **Каталог данных не переносится кодом.** Хаб, MCP-серверы открытых сессий Claude и CLI открывают одну базу; перенос
«на лету» при старте любого из них рискует WAL и гонкой. Код только отказывает с подсказкой (требование «Каталог
данных прежнего имени»), перенос — шаг скрипта при остановленном хабе.
5. **Скрипт переключения в репозитории** (`scripts/cutover.sh` — обёртка над `scripts/cutover.py` на stdlib, вне пакета
хаба), сухой прогон по умолчанию. Шагов много, они касаются
launchd, двух чужих репозиториев и user scope Claude; руками их легко сделать не в том порядке (I-2 wiki-module).
Скрипт одноразовый, после переключения остаётся в истории как образец; тесты — на сухой прогон и проверки шага 1
(во временном `HOME`), без launchd.
6. **Переименование репозитория в Gitea — руками владельца** в интерфейсе (Settings → Repository name). Gitea оставляет
перенаправление со старого адреса; `tea` и `origin` после этого работают по новому адресу. Скрипт проверяет, что
переименование сделано, и меняет `origin`.
7. **Checkout переезжает в `jira-bridge/sdlc-hub`**, workspace `jira-bridge` остаётся: от его пути зависят каталог
памяти Claude, workspace `CLAUDE.md`, путь общей папки реле (`…/utm/rshb/jira-bridge`) и настройки агентов на
виртуалке. Переименование workspace — отдельно, если понадобится.
8. **Ключи `localStorage` — с разовым переносом** из `jira-hub-*`: браузер владельца не должен снова просить токен и
терять свёрнутость панели и легенды. Ключи доски `graph-*` имени хаба не содержат и не меняются.
9. **История не переписывается**: `docs/superpowers/plans/`, `openspec/changes/archive/` остаются со старыми именами.
Раздел `Purpose` спек `hub-api`, `mcp`, `web-app` (дельтами не меняется) правится в PR архива.
10. **Агенты без релиза.** `src/agent.py` и `src/run.py` jira-agent и eva-agent не трогаются (строки документации — со
следующим релизом); README, CLAUDE.md, ARCHITECTURE.md, `agent.example.json` и `scripts/e2e-hub.sh` eva-agent —
мелкими PR в своих репозиториях (bounded, без change).
11. **Порядок с #98 (веб под модули).** Переименование сливается первым; ветка #98 перебазируется на него. Бренд и
ключи хранилища меняет этот change, устройство боковой панели — #98.
## Переключение (для владельца)
1. Слить PR этого change; переименовать репозиторий в Gitea `aep/jira-hub` → `aep/sdlc-hub`.
2. Закрыть или не трогать сессии Claude с MCP хаба (после переключения — `/mcp` reconnect).
3. `git -C ~/projects/jira-bridge/jira-hub pull --ff-only` и сразу `bash ~/projects/jira-bridge/jira-hub/scripts/cutover.sh`
— сухой прогон, проверить вывод. Между pull и переключением работающий хаб живёт на загруженном коде, а новые сессии
Claude не поднимут MCP — окно в несколько минут.
4. `bash ~/projects/jira-bridge/jira-hub/scripts/cutover.sh --apply`.
5. Просмотреть правки в awp-ca и stocks_drrk (`.mcp.json`, `.claude/`, `CLAUDE.md` awp-ca; копии `*.pre-sdlc` рядом) и
удалить копии. Это не git-репозитории — коммитить нечего.
6. Проверить: `agent_status` через `sdlc-jira`, `status` через `sdlc-wiki`, веб `http://127.0.0.1:8790/app/` без
повторного входа.
Откат: остановить `ru.aepif.sdlc-hub`, перенести каталоги обратно, вернуть plist `ru.aepif.jira-hub` из README
предыдущей версии, `git checkout` прежнего коммита, вернуть записи MCP — порядок в README.
## Risks / Trade-offs
- **Сессии Claude с открытым MCP** держат старый путь к пакету: после переноса checkout их серверы падают до
reconnect. Принято: переключение — разовое событие владельца.
- **codegraph-индексы** в `.codegraph/` checkout и worktree содержат абсолютные пути: после переноса — `codegraph init`
заново (шаг в сводке скрипта).
- **Гонка с #98**: массовый перенос `src/jira_hub` → `src/sdlc_hub` конфликтует с любой веткой, трогающей Python;
#98 — только `web/`, поэтому конфликт ограничен брендом и ключами хранилища (решение 11).
## Decisions made without discussion
Владелец 24.10.2026 ответил «делай» на вопросы brainstorming — все решения ниже приняты агентом.
| # | Дата | Решение | Обоснование | Цена ошибки |
|---|---|---|---|---|
| 1 | 24.10.2026 | Бренд «SDLC Hub» | имя из решения владельца, латиница как в имени репозитория | правка строки в вебе |
| 2 | 24.10.2026 | Без псевдонима `jira-hub` | явный отказ лучше тихой работы старых записей | вернуть точку входа в `pyproject.toml` |
| 3 | 24.10.2026 | MCP `sdlc-jira`/`sdlc-wiki`, модуль обязателен | симметрия модулей, ядро без «jira по умолчанию» | переименовать серверы ещё раз во всех `.mcp.json` |
| 4 | 24.10.2026 | Каталог данных переносит скрипт, код только отказывает | гонка открытых баз при переносе на лету | ручной `mv` при остановленном хабе |
| 5 | 24.10.2026 | Скрипт `scripts/cutover.sh` с сухим прогоном | много шагов в чужих конфигурациях, порядок важен | шаги руками по README |
| 6 | 24.10.2026 | Gitea переименовывает владелец | действие на сервере, вне репозитория | — |
| 7 | 24.10.2026 | Workspace `jira-bridge` не переименовывается | от пути зависят память Claude, реле, агенты | отдельный change позже |
| 8 | 24.10.2026 | Перенос ключей `localStorage` | не просить токен заново | повторный вход в веб |
| 9 | 24.10.2026 | История (планы, архив) не меняется | это запись прошлого | — |
| 10 | 24.10.2026 | Агенты без релиза, документация — мелкими PR | протокол не меняется | строки документации в `agent.py` со старым именем до следующего релиза |
| 11 | 24.10.2026 | Сначала переименование, потом #98 | #98 перебазируется на новые пути | перебазирование веток |
| 12 | 24.10.2026 | R-1: трейлер коммитов `Co-Authored-By: Claude Sonnet 5.5` вместо `Opus 5.5` из плана | указание системы сессии новее плана | правка трейлера |
| 13 | 24.10.2026 | R-2: правки web/playwright.config.ts, web/scripts/seed-hub.py и JIRA_HUB_URL→SDLC_HUB_URL (vite.config.ts) сделаны уже в Task 1 | без них e2e, test-hub.sh и seed-скрипт ломаются между задачами | откат трёх файлов |