From cd8f5505b02c56a3b04f30b78851097e009ad787 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sat, 24 Oct 2026 02:33:10 +0400 Subject: [PATCH] =?UTF-8?q?docs(openspec):=20wiki-module=20=E2=80=94=20?= =?UTF-8?q?=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=20Task=207,=20R-6=20?= =?UTF-8?q?(#91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- openspec/changes/wiki-module/design.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/openspec/changes/wiki-module/design.md b/openspec/changes/wiki-module/design.md index 1c2c75d..a1e42db 100644 --- a/openspec/changes/wiki-module/design.md +++ b/openspec/changes/wiki-module/design.md @@ -556,3 +556,27 @@ jira безвреден. экранирует `\ [ ] <` и `_`/`*` на границе слова. `@` не экранируется. Цена ошибки: сырой `.md` с `<`. 56. Известные края (отложены): вложение в `` страницы/внешней ссылки, вложенный `` между `` и ``, хвостовой `\` в тексте ссылки, пробелы/скобки во внешнем href, дубликаты `ref` (побеждает последний). + +Решения исполнителя Task 7 и рулинг R-6 (2026-10-24): + +57. **R-6.** В контракт `CommandHooks` ядра добавлены два необязательных хука: `before_result` (вызывается до + транзакции отчёта; нужен, чтобы перевод и запись файлов шли вне `BEGIN IMMEDIATE`, решение 10) и `abort_result` + (`queue.report_result` вызывает его в `finally`, если отчёт не дошёл до `after_result`). У jira оба `None`. Цена + ошибки: правка контракта модуля; сборку можно вернуть в `on_result` ценой блокировки очереди на время сборки. +58. Идентификаторы вложений выделяются короткой транзакцией до сборки копии; при отбрасывании или сбое добавленные + строки `state='none'` удаляются (`abort_result`). Подготовка хранится в памяти процесса; после рестарта хаба + повтор отчёта готовит заново. Цена ошибки: сироты до следующей синхронизации. +59. Подготовка идёт в `.<имя>.new.` под per-label `Lock` от `before_result` до `after_result`/`abort_result`; + второй одновременный `done` ждёт первого (без таймаута) и затем выходит идемпотентно. `finish_pending_swaps` + продвигает `.new*` только при наличии `_tree.json`. Цена ошибки: долгая сборка проекта задерживает отчёты по нему. +60. `codes[0]` обязан быть корнем команды; страницы без родителя и циклы цепляются к корню; `NN` в имени каталога — + позиция среди соседей (у корня каталог по названию, без номера); дубликаты имён — `_2`, `_3` без учёта регистра; + имя до 80 символов и 200 байт. Цена ошибки: другие имена каталогов. +61. FTS-таблица `wiki_page_fts` создаётся лениво в `search.ensure` (не в `schema.SQL`), эталон `schema` не меняется; + токены запроса — `\w+`. Сбой подмены каталога откатывает строки и переводит команду в `failed`. Падение внешнего + COMMIT после подмены оставляет новые файлы при старых строках до следующей синхронизации. Цена ошибки: лишняя + синхронизация. +62. `failed_at` пишется при `failed`, отброшенной и отменённой синхронизации (иначе автотик ставит пакеты каждый тик); + `housekeeping_tick` удаляет стадию команд не в `queued`/`claimed`. Лимиты `stage`: `code` 200, `title` 1000, `url` + 4000, до 20000 страниц на команду; формат `DOC-\d+` для `code` не навязывается. Пустые `parent_code`/`url` — `None`. + `ValueError` из `before_result` → 500; `sqlite3.OperationalError` из подготовки → 500 (повтор агентом).