Вики: история правок — лента и дифф в MCP и вебе (#140) #141

Merged
aep merged 13 commits from feat/140-wiki-history into main 2026-10-28 13:01:47 +03:00
Owner

Closes #140. Агентская часть — aep/eva-agent#7 (PR в eva-agent); выкатываются парой.

Что сделано

  • История правок страниц. wiki_sync получает в выдаче known_versions; агент шлёт опубликованные версии страниц дерева POST /agent/wiki/versions; хаб переводит их в Markdown вне транзакции, хранит (wiki_version, стадия wiki_version_stage, wiki_history.history_at) и считает «+/−» в prepare. Только страницы дерева проекта, только опубликованные правки. Агент v1 работает как прежде — история не пополняется.
  • HTTP API. GET /wiki/changes (лента за период, фильтр автора без учёта регистра, кириллица), GET /wiki/pages/{code}/versions, GET /wiki/pages/{code}/diff (unified diff частями по 20 000); у страницы — modified_at, modified_by, versions; у состояния — history_at.
  • MCP sdlc-wiki. Новые changes, diff; строка «изменено» в page; sync отвечает коротко («поставлено / ок: синхронизировано / ошибка»); история в status. Чтение — только копия хаба. Сервер sdlc-jira не изменился (эталон).
  • Веб. Общая «Лента» ядра /app/feed (пункт под «Обзором») с источниками модулей через HubModule.feed: Jira (виды событий) и Вики (правки по странице). Окно правки с диффом /app/wiki/pages/{code}/versions/{version} поверх ленты: предыдущая/следующая правка, «Показать дальше», «Открыть страницу». /app/jira/feed перенаправляет на /app/feed. На «Обзоре» — «Лента» (Jira) и «Правки» (Вики).

Спека: openspec/changes/wiki-history/ (proposal, design — решения 1–15, П-1…П-12, «Decisions made without discussion»).

Проверки

  • make check: pytest 1293 passed, lint ok, vitest 79 файлов / 799 passed.
  • npm run build ok; Playwright 61 passed (52 skipped — снимки экрана, только SCREENS=1).
  • Контракт с агентом: HUB_SRC=<эта ветка> bash scripts/e2e-hub.sh в eva-agent — первая загрузка версий и догрузка новой версии, e2e: ok.
  • Ревью: по задаче (sonnet) на каждой из 8 задач, финальное ревью ветки (opus) — «With fixes», Critical/Important исправлены (1de07a4).

Rulings I made

  • R-1 line_delta берёт unified_diff()[2:], а не отбор по +++/--- (иначе теряются строки ++x/--x). Цена ошибки: при смене формата difflib «+/−» искажаются на две строки.
  • R-2 повторное ревью исправления задачи 3 (10 строк, RED→GREEN) сделал контроллер, не свежий ревьюер. Цена ошибки: пропущенная регрессия; финальное ревью её не нашло.
  • I-1 (финальное M-1, поднято до Important) «за период изменений нет» — по П-11: если хотя бы один источник без своего сообщения. Иначе в окне выкатки (агент v1) пустая Jira молчала.
  • I-2 (T7.1, поднято до Important) строки диффа без зазора 12 px — читаемость главного результата.
  • Решения без обсуждения из brainstorming и плана (постраничная выборка версий, время правки = cmf_created_at, вложения в версиях текстом, сбой версий = сбой синхронизации, дифф по запросу, короткий sync, адреса /app/feed и окна правки, фильтр автора подстрокой, П-1…П-12) — в design.md.

Отложено (follow-up)

T1.1, T1.3, T1.4 (ruff нет в окружении), T2.1, T2.2, T3.1, T3.2, T3.3, T4.1, T4.2, T5.2, T5.3, T6.1, T6.2, T6.3, T7.2, T7.3, M-2 (OverflowError на краях дат → 500), M-3, M-4 (sync wait — ложное «ок» при сменённом корне). Подробно — таблица Findings в ledger, попадут в issue «Follow-ups from #140».

Выкатка (владелец)

  1. git pull → launchctl kickstart -k gui/$(id -u)/ru.aepif.sdlc-hub → make web → /mcp reconnect. Новые таблицы создаются при подключении, миграции нет; прежний код с такой базой работает.
  2. Публикация eva-agent v2: uv run sdlc-hub agent publish --module wiki ../eva-agent/src/agent.py.
  3. После status с v2 и первой синхронизации — проверить в логе агента строку «N из M версий без автора» (если есть — cmf_author у версий не раскрывается); затем поднять wiki_min_agent_version до 2.

🤖 Generated with Claude Code

Closes #140. Агентская часть — aep/eva-agent#7 (PR в eva-agent); выкатываются парой. ## Что сделано - **История правок страниц.** `wiki_sync` получает в выдаче `known_versions`; агент шлёт опубликованные версии страниц дерева `POST /agent/wiki/versions`; хаб переводит их в Markdown вне транзакции, хранит (`wiki_version`, стадия `wiki_version_stage`, `wiki_history.history_at`) и считает «+/−» в `prepare`. Только страницы дерева проекта, только опубликованные правки. Агент v1 работает как прежде — история не пополняется. - **HTTP API.** `GET /wiki/changes` (лента за период, фильтр автора без учёта регистра, кириллица), `GET /wiki/pages/{code}/versions`, `GET /wiki/pages/{code}/diff` (unified diff частями по 20 000); у страницы — `modified_at`, `modified_by`, `versions`; у состояния — `history_at`. - **MCP `sdlc-wiki`.** Новые `changes`, `diff`; строка «изменено» в `page`; `sync` отвечает коротко («поставлено / ок: синхронизировано / ошибка»); история в `status`. Чтение — только копия хаба. Сервер `sdlc-jira` не изменился (эталон). - **Веб.** Общая «Лента» ядра `/app/feed` (пункт под «Обзором») с источниками модулей через `HubModule.feed`: Jira (виды событий) и Вики (правки по странице). Окно правки с диффом `/app/wiki/pages/{code}/versions/{version}` поверх ленты: предыдущая/следующая правка, «Показать дальше», «Открыть страницу». `/app/jira/feed` перенаправляет на `/app/feed`. На «Обзоре» — «Лента» (Jira) и «Правки» (Вики). Спека: `openspec/changes/wiki-history/` (proposal, design — решения 1–15, П-1…П-12, «Decisions made without discussion»). ## Проверки - `make check`: pytest 1293 passed, lint ok, vitest 79 файлов / 799 passed. - `npm run build` ok; Playwright 61 passed (52 skipped — снимки экрана, только `SCREENS=1`). - Контракт с агентом: `HUB_SRC=<эта ветка> bash scripts/e2e-hub.sh` в eva-agent — первая загрузка версий и догрузка новой версии, `e2e: ok`. - Ревью: по задаче (sonnet) на каждой из 8 задач, финальное ревью ветки (opus) — «With fixes», Critical/Important исправлены (1de07a4). ## Rulings I made - **R-1** `line_delta` берёт `unified_diff()[2:]`, а не отбор по `+++`/`---` (иначе теряются строки `++x`/`--x`). Цена ошибки: при смене формата difflib «+/−» искажаются на две строки. - **R-2** повторное ревью исправления задачи 3 (10 строк, RED→GREEN) сделал контроллер, не свежий ревьюер. Цена ошибки: пропущенная регрессия; финальное ревью её не нашло. - **I-1** (финальное M-1, поднято до Important) «за период изменений нет» — по П-11: если хотя бы один источник без своего сообщения. Иначе в окне выкатки (агент v1) пустая Jira молчала. - **I-2** (T7.1, поднято до Important) строки диффа без зазора 12 px — читаемость главного результата. - Решения без обсуждения из brainstorming и плана (постраничная выборка версий, время правки = `cmf_created_at`, вложения в версиях текстом, сбой версий = сбой синхронизации, дифф по запросу, короткий `sync`, адреса `/app/feed` и окна правки, фильтр автора подстрокой, П-1…П-12) — в design.md. ## Отложено (follow-up) T1.1, T1.3, T1.4 (ruff нет в окружении), T2.1, T2.2, T3.1, T3.2, T3.3, T4.1, T4.2, T5.2, T5.3, T6.1, T6.2, T6.3, T7.2, T7.3, M-2 (`OverflowError` на краях дат → 500), M-3, M-4 (`sync wait` — ложное «ок» при сменённом корне). Подробно — таблица Findings в ledger, попадут в issue «Follow-ups from #140». ## Выкатка (владелец) 1. `git pull` → `launchctl kickstart -k gui/$(id -u)/ru.aepif.sdlc-hub` → `make web` → `/mcp` reconnect. Новые таблицы создаются при подключении, миграции нет; прежний код с такой базой работает. 2. Публикация eva-agent v2: `uv run sdlc-hub agent publish --module wiki ../eva-agent/src/agent.py`. 3. После `status` с v2 и первой синхронизации — проверить в логе агента строку «N из M версий без автора» (если есть — `cmf_author` у версий не раскрывается); затем поднять `wiki_min_agent_version` до 2. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 13 commits 2026-10-28 12:48:47 +03:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- schema: wiki_version, wiki_version_stage, wiki_history (без миграций, IF NOT EXISTS)
- history.utc: время версии в UTC; без смещения или не строка — None
- convert.to_markdown(file_links=False): вложение текстом «📎 имя», список файлов пуст
- stage.accept_versions + POST /agent/wiki/versions (agent wiki): проверка формы, перевод вне транзакции
- эталоны baseline (routes, schema) и документы: design.md (П-1…П-12), ARCHITECTURE.md

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Маршруты GET /wiki/changes, /wiki/pages/{code}/versions, /wiki/pages/{code}/diff;
у страницы — modified_at, modified_by, versions; у состояния — history_at.
Дифф режется по 20 000 символов, фильтр автора без учёта регистра в Python.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 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>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep merged commit a50ef9dcb1 into main 2026-10-28 13:01:47 +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/sdlc-hub#141
No description provided.