WEB board

всеканоны и докиворкеры↗ iOS↗ Легаси
WEB-283 · Эпик · Редактор · web

ЭПИК: движок редактора Gate C (docsession) — леги 1-9 + продуктовые хвосты

Закрыт P1 · важно ведёт: —
Суть
## Суть
Эпик гейта C движка (docsession): леги 1–9 + продуктовые хвосты — realtime C07, публикация без длинных транзакций, Redis-многокомнатность, контролируемый пишущий путь.

## Где мы сейчас (13.09.2026)
Прод = l115j (133fe00c). Лестница гейтов: Gate A контракт ✅ → Gate B библиотека (F01–F06) ✅ → Gate C legacy shadow закрыта 23.08 (R22G-F4, WEB-089 CLOSED-VERIFIED) → Gate D controlled writer посажен l62 (WEB-324) → Gate E mutating AI принята 28.08 (ACCGATEE9 GO) → Gate F collab NO-GO by design (W1 d1b71160b6). Хвосты 2332 (публикация >5 с) и 2344 (Redis FK) закрыты числами 13.09 замерами 3627 (roleschains5 batched publication 3/3, session-turn 13/13, url-based pg 3/3, realtime mirror multinode 1/1). Осталось: сверка лег 1–9 «принято↔посажено↔включено» (перечень лег 1–9 в карточке отсутствует — сведено что известно в LEGS-TABLE.md) и финальный вердикт canary 3456/3461 (ВЕРДИКТА НЕТ, требуется прогон — см. остаток).

## Хронология
- 16–23.08: Gate C (R4→R22G-F4) закрыт аудитом GO (WEB-089 CLOSED-VERIFIED).
- 28.08: Gate E принята ACCGATEE9 GO (флаг выключен); посажена l64 тёмной.
- 06.09: C07 durable catch-up принят (2398); realtime Redis круг 1 NO-GO (2344 FK).
- 09.09: две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён.
- 10.09: 3438 bounded GO; 3456/3461 в работе на A2.
- 13.09: замеры 3627/3636/roleschains6 — хвосты 2332/2344 и правка вдвоём закрыты числами (roleschains5 batched publication 3/3, session-turn 13/13, url-based pg 3/3, realtime mirror multinode 1/1, правка вдвоём с настоящим отрицательным контролем 3/3, roleschains6 2/2; источник — комментарии координатора 13.09 08:26Z/09:20Z/09:35Z).

## Карта документов и кода
- src/lib/realtime/server.ts, documentSessionVersionedHub.ts — realtime/multinode.
- src/lib/realtime/multinodeConfig.ts — выбор адаптера (process-local/Redis).
- src/lib/rag/sourceChunkWriter.ts, chunkGeneration.ts — публикация поколения чанков.
- src/app/api/realtime/session-turn/route.ts — Redis FK 2344.
- src/lib/document-session/ai-operation-ledger.ts, gated-writer.ts — защита от двойной AI-операции.
- Замеры: /home/wave/waves/3627EDITORMEASURE-evidence/, shift-20260912-resume/colG/; roleschains6-coordinator.out.

## Остаток
1. Сверка лег 1–9 по статусу accepted/landed/enabled — НЕ СДЕЛАНА. Перечня лег 1–9 в карточке нет (есть только лестница Gate A–F + частичные следы leg 8 и leg 9 из R4/16.08); полное определение в board/specs/ENGINE-GATEC-EPIC.md, которого нет во входах. Что известно — см. LEGS-TABLE.md. Ответственный: координатор (достать спек и сверить по волнам).
2. Финальный вердикт durable proof 3456 / canary negative 3461 — ВЕРДИКТА НЕТ, требуется прогон (что именно прогнать — см. WEB-086 остаток).
3. Браузерная приёмка Gate E — волна 3645 в полёте (WEB-325).

## Критерий закрытия
Таблица лег 1–9 «принято↔посажено↔включено» с ссылками на волну/линию для каждой — НЕ СОБРАНА (перечень лег не в карточке, см. LEGS-TABLE.md); числа по 2332 (roleschains5 3/3) и 2344 (session-turn 13/13) — ЗАПИСАНЫ (3627); финальный вердикт 3456/3461 — НЕТ (требуется прогон); браузер-приёмка Gate E GO — ждёт 3645 (WEB-325).

---

## История (старое тело)

## Суть
Эпик гейта C движка (docsession): леги 1–9 + продуктовые хвосты — realtime C07, публикация без длинных транзакций, Redis-многокомнатность, контролируемый пишущий путь.

## Где мы на 12.09
Лестница гейтов: Gate A контракт ✅ → Gate B библиотека (F01–F06) → Gate C legacy shadow ЗАКРЫТ 23.08 (R22G-F4, WEB-089 CLOSED-VERIFIED) → Gate D controlled writer посажен l62 (WEB-324) → Gate E mutating AI принята 28.08 (ACCGATEE9 GO) → Gate F collab NO-GO by design (W1 d1b71160b6). Ядро C/D/E принято и посажено; 09.09 две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён. 10.09 3438 bounded GO; durable proof 3456 + canary negative 3461 в работе. Runtime Gate E не включён.

## Остаток
1. Publication tx >5 с (2332) — свежего подтверждения закрытия нет.
2. Redis-hit Prisma FK → 404/500 (2344) — свежего подтверждения закрытия нет.
3. Леги 1–9 продуктовые хвосты — отдельной сверки не было.
4. Runtime Gate E не включён.

## Кто/что дальше
Приёмка 3456/3461 на A2; сверка хвостов 2332/2344 и лег 1–9; включение Gate E — после лестницы C→D→E.

## История
- 16–23.08: Gate C (R4→R22G-F4) закрыт аудитом GO (WEB-089 CLOSED-VERIFIED).
- 28.08: Gate E принята ACCGATEE9 GO (флаг выключен); посажена l64 (6508f013) тёмной.
- 06.09: C07 durable catch-up принят (2398); realtime Redis круг 1 NO-GO (2344 FK).
- 09.09: две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён.
- 10.09: 3438 bounded GO; 3456/3461 в работе; Gate E runtime не включён.

---

## история (тело до 13.09.2026)

## Суть
Эпик гейта C движка (docsession): леги 1–9 + продуктовые хвосты — realtime C07, публикация без длинных транзакций, Redis-многокомнатность, контролируемый пишущий путь.

## Где мы сейчас (13.09.2026)
Прод = l115j (133fe00c). Лестница гейтов: Gate A контракт ✅ → Gate B библиотека (F01–F06) ✅ → Gate C legacy shadow закрыта 23.08 (R22G-F4, WEB-089 CLOSED-VERIFIED) → Gate D controlled writer посажен l62 (WEB-324) → Gate E mutating AI принята 28.08 (ACCGATEE9 GO) → Gate F collab NO-GO by design (W1 d1b71160b6). Хвосты 2332 (публикация >5 с) и 2344 (Redis FK) закрыты числами 13.09 замерами 3627 (roleschains5 batched publication 3/3, session-turn 13/13, url-based pg 3/3, realtime mirror multinode 1/1). Осталось: сверка лег 1–9 «принято↔посажено↔включено» и формальный финальный вердикт canary 3456/3461.

## Хронология
- 16–23.08: Gate C (R4→R22G-F4) закрыт аудитом GO (WEB-089 CLOSED-VERIFIED).
- 28.08: Gate E принята ACCGATEE9 GO (флаг выключен); посажена l64 тёмной.
- 06.09: C07 durable catch-up принят (2398); realtime Redis круг 1 NO-GO (2344 FK).
- 09.09: две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён.
- 10.09: 3438 bounded GO; 3456/3461 в работе на A2.
- 13.09: замеры 3627/3636/roleschains6 — хвосты 2332/2344 и правка вдвоём закрыты числами.

## Карта документов и кода
- src/lib/realtime/server.ts, documentSessionVersionedHub.ts — realtime/multinode.
- src/lib/realtime/multinodeConfig.ts — выбор адаптера (process-local/Redis).
- src/lib/rag/sourceChunkWriter.ts, chunkGeneration.ts — публикация поколения чанков.
- src/app/api/realtime/session-turn/route.ts — Redis FK 2344.
- src/lib/document-session/ai-operation-ledger.ts, gated-writer.ts — защита от двойной AI-операции.
- Замеры: /home/wave/waves/3627EDITORMEASURE-evidence/, shift-20260912-resume/colG/; roleschains6-coordinator.out.

## Остаток
1. Сверка лег 1–9 по статусу accepted/landed/enabled — отдельной сверки не было (каждый легас до сих пор не сведён в одну таблицу). Ответственный: одна волна/координатор.
2. Финальный вердикт durable proof 3456 / canary negative 3461 — формально не записан (см. WEB-086).
3. Браузерная приёмка Gate E — волна 3645 в полёте (WEB-325).

## Критерий закрытия
Таблица лег 1–9 «принято↔посажено↔включено» с ссылками на волну/линию для каждой; числа по 2332 (публикация <= бюджета, roleschains5 3/3) и 2344 (session-turn 13/13) в карточке; финальный вердикт 3456/3461; браузер-приёмка Gate E GO.

---

## История (старое тело)

## Суть
Эпик гейта C движка (docsession): леги 1–9 + продуктовые хвосты — realtime C07, публикация без длинных транзакций, Redis-многокомнатность, контролируемый пишущий путь.

## Где мы на 12.09
Лестница гейтов: Gate A контракт ✅ → Gate B библиотека (F01–F06) → Gate C legacy shadow ЗАКРЫТ 23.08 (R22G-F4, WEB-089 CLOSED-VERIFIED) → Gate D controlled writer посажен l62 (WEB-324) → Gate E mutating AI принята 28.08 (ACCGATEE9 GO) → Gate F collab NO-GO by design (W1 d1b71160b6). Ядро C/D/E принято и посажено; 09.09 две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён. 10.09 3438 bounded GO; durable proof 3456 + canary negative 3461 в работе. Runtime Gate E не включён.

## Остаток
1. Publication tx >5 с (2332) — свежего подтверждения закрытия нет.
2. Redis-hit Prisma FK → 404/500 (2344) — свежего подтверждения закрытия нет.
3. Леги 1–9 продуктовые хвосты — отдельной сверки не было.
4. Runtime Gate E не включён.

## Кто/что дальше
Приёмка 3456/3461 на A2; сверка хвостов 2332/2344 и лег 1–9; включение Gate E — после лестницы C→D→E.

## История
- 16–23.08: Gate C (R4→R22G-F4) закрыт аудитом GO (WEB-089 CLOSED-VERIFIED).
- 28.08: Gate E принята ACCGATEE9 GO (флаг выключен); посажена l64 (6508f013) тёмной.
- 06.09: C07 durable catch-up принят (2398); realtime Redis круг 1 NO-GO (2344 FK).
- 09.09: две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён.
- 10.09: 3438 bounded GO; 3456/3461 в работе; Gate E runtime не включён.

---

## история (тело до 13.09.2026)

## Суть
Эпик гейта C движка (docsession): леги 1–9 + продуктовые хвосты — realtime C07, публикация без длинных транзакций, Redis-многокомнатность, контролируемый пишущий путь.

## Где мы на 12.09
Лестница гейтов: Gate A контракт ✅ → Gate B библиотека (F01–F06) → Gate C legacy shadow ЗАКРЫТ 23.08 (R22G-F4, WEB-089 CLOSED-VERIFIED) → Gate D controlled writer посажен l62 (WEB-324) → Gate E mutating AI принята 28.08 (ACCGATEE9 GO) → Gate F collab NO-GO by design (W1 d1b71160b6). Ядро C/D/E принято и посажено; 09.09 две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён. 10.09 3438 bounded GO; durable proof 3456 + canary negative 3461 в работе. Runtime Gate E не включён.

## Остаток
1. Publication tx >5 с (2332) — свежего подтверждения закрытия нет.
2. Redis-hit Prisma FK → 404/500 (2344) — свежего подтверждения закрытия нет.
3. Леги 1–9 продуктовые хвосты — отдельной сверки не было.
4. Runtime Gate E не включён.

## Кто/что дальше
Приёмка 3456/3461 на A2; сверка хвостов 2332/2344 и лег 1–9; включение Gate E — после лестницы C→D→E.

## История
- 16–23.08: Gate C (R4→R22G-F4) закрыт аудитом GO (WEB-089 CLOSED-VERIFIED).
- 28.08: Gate E принята ACCGATEE9 GO (флаг выключен); посажена l64 (6508f013) тёмной.
- 06.09: C07 durable catch-up принят (2398); realtime Redis круг 1 NO-GO (2344 FK).
- 09.09: две потери текста (3175) починены, посажены l114j; Redis/multinode вооружён.
- 10.09: 3438 bounded GO; 3456/3461 в работе; Gate E runtime не включён.
Доказательства

[2026-08-25 ~03:30] Массовый сбор телеметрии по команде owner (голос 23:27 «запусти в массовости, пускай синтетика»): shadowrun5 на M4 (клон shadowrun4-soak.mjs, релиз-штамп v4-0ac410ac0, окно 3ч, tmux -L gui сессия shadowrun5). Синтетика: тетради 5К/50К, inserts/deletes/unicode/emoji/undo/redo/reopen/history-jumps через обычный UI, admin-QA учётка. Пруф: beacon-статусы 200 (первые 21 шт), серверный JSONL 186→456 записей за ~30 мин (/home/pi/note-clone/shared/telemetry/gatec-shadow-w1.jsonl). Свежие записи чистые: contentHashLegacy==contentHashShadow, historyDepth 13/13, corruption 0. Дальше: снять JSONL по окончании окна → вердикт Gate C → Gate D. Evidence волны: M4 /Users/milamarty/work/shadowrun5-evidence.json, отчёт SHADOWRUN5-REPORT.md.

[2026-08-25 ~07:35] ⭐ ВЕРДИКТ Gate C (телеметрия) из 19167 записей вечного архива (owner: «телеметрию закончили снимать»): contentHash совпал 18848 (98%), historyDepth совпал 18848 (98%), primarySafety corruption = 0 (НОЛЬ — движок ни разу не испортил контент/историю, критическая безопасность). divergenceKind: none=18397 (96% от всех, 97.6% от w1-comparator), anchors=451, unrepresented-dom-mutation=319 (последнее — producer w2-synthetic, класс WEB-347). Producers: w1-comparator 18848, w2-synthetic 319. ВЕРДИКТ: движок БЕЗОПАСЕН (0 порчи) и 98% верен; остаток ~2% = ДВА известных класса расхождений (anchors 451 — позиции курсора/выделения; dom-mutation 319 — синтетика), НЕ порча данных. Это НЕ блокер безопасности, но следующий инженерный шаг ПЕРЕД включением Gate D (движок пишет) — добить anchors+dom-mutation до нуля. Родня: [[WEB-324]] Gate D (включать после этого), [[WEB-347]] dom-mutation класс, [[WEB-354]] history-инвариант.

[2026-08-25 ~07:40] OWNER-APPROVED (tg 06:32) волна GATEC-2%: добить anchors(451)+dom-mutation(319) до чистого Gate C → включение Gate D. Запущена на A1 (Luna xhigh, свой worktree от посадки 52). Тень остаётся тенью, флаги тёмные. После посадки — повторный соук подтвердит ноль. Маркер GATEC2_DONE.

[2026-08-27 связь] Gate C: сегодня вся работа шла по Gate D (WEB-324) — найдено и починено ТРИ корня подряд: React 19 seam (onBeforeInput через textInput), lifecycle (dispose при StrictMode replay + молчаливый return на disposed writer), неработавший kill-switch и divergence на пробеле/выделении ZWJ. Живая браузерная приёмка (accgd4..accgd7) — первая в истории этой линии. Gate C-контур на проде не менялся.

## 2026-08-28 ~12:10Z — ступень E: замысел принят, две поломки (координатор Фабл)
ACCGATEE7 = NO-GO. Переделка gatee7 признана верной по устройству (замок перенесён из памяти вкладки в IndexedDB, `keyPath: operationKey`, одна `readwrite`-транзакция; ответы на три вопроса даны; `unavailable` виден через маячок, `console.error`, DOM-пометки, сообщение). Но два блокирующих:
1. **Мусор в журнале принимается как законная запись.** `ai-operation-ledger.ts:82-103` проверяет только `typeof string && length > 0`, не формат ключа `ai-operation-v1-*` и не схему токена. Доказано: `operationKey: "   "`, чужой `legacy-foreign-key` и токен из пробелов прошли `asLedgerRecords`, захваты вернули `claimed` вместо отказа.
2. **Столкновение причинных ключей = МОЛЧАЛИВАЯ ПОТЕРЯ ПРАВКИ.** `deriveAiOperationId` (`:47-57`) и UTF-8 helper (`sha256.ts:27-42`) приводят одиночный суррогат `0xd800` и `U+FFFD` к одному байту ДО хеширования. Две разные операции получили ключ `ai-operation-v1-ai_GmbD9si94AenKKx5T4JK9x5aCLCdFId4_4CArBgE`; вторая законная правка объявлена повтором и не применена (`gated-writer.ts:1020-1045`).
ДЕЙСТВИЕ: волна `gatee8`. По второму дефекту требуется письменное доказательство, что пара разных операций с одним ключом более невозможна, либо честно названный остаточный риск. Флаг E не включаем.


## 2026-08-28 — ПОЛНЫЙ СЛЕД ДЛЯ ПОДХВАТА (координатор Фабл)
Чтобы новый агент не играл в детектива: ниже вся эволюция, где лежат отчёты и что делать дальше.

**Линия:** движок редактора, ступень E (защита от двойной AI-операции).
**Эволюция:**
1. `gatee6` — подключила боевой CAS-адаптер в `EditorModal`; заявила 67/67, Gate D 23/23, Orb 290/290. Отчёт: `A1:/home/ubuntu/waves/GATEE6-REPORT.md`.
2. `ACCGATEE6` = **NO-GO**, 4 дефекта, три одного класса — защита живёт в памяти вкладки. Отчёт: `A1:/home/ubuntu/waves/ACCGATEE6-REPORT.md`. Ключевые места: замок в `WeakMap` (`src/lib/document-session/ai-operation-ledger.ts:158-180`), счётчик вместо причинного ID (`src/components/modals/EditorModal.tsx:1322,4321`), потеря отказа журнала (`src/lib/document-session/gated-writer.ts:1038-1040`, `EditorModal.tsx:4328-4335`), расхождение на границе inline (`gated-writer.ts:892-915`).
3. `gatee7` — **переделка, а не заплатка**: замок перенесён в IndexedDB (`keyPath: operationKey`, одна `readwrite`-транзакция), письменные ответы на три вопроса, `unavailable` виден (маячок, `console.error`, DOM-пометки, сообщение). Отчёт: `A1:/home/ubuntu/waves/GATEE7-REPORT.md`.
4. `ACCGATEE7` = **NO-GO**: мусор в журнале принимается (`ai-operation-ledger.ts:82-103` проверяет только `typeof string && length>0`); **столкновение причинных ключей** — `0xd800` и `U+FFFD` сводятся к одному байту до хеширования (`:47-57` + `src/lib/document-session/sha256.ts:27-42`), две разные операции получают один ключ, вторая молча не применяется = потеря правки человека. Отчёт: `A1:/home/ubuntu/waves/ACCGATEE7-REPORT.md`.
5. `gatee8` — чинила оба. `ACCGATEE8` = **NO-GO** (отчёт `A1:/home/ubuntu/waves/ACCGATEE8-REPORT.md`).
6. `gatee9` — **идёт сейчас**. Третий круг по узлу, поэтому в бриф вписано правило: менять способ, а не латать точку; письменно ответить, может ли пара разных операций получить один ключ.
**Состояние:** флаг E НЕ включён. Браузерная приёмка глазами — отдельный невыполненный шаг.
**Дальше:** дождаться `GATEE9_DONE` → приёмка → только потом обсуждать включение флага.
**Связанное:** общий проверяльщик формы (`shapeguard`) закрывает тот же класс в других участках — см. WEB-320.

[28.08 ~12:10Z Фабл] **Gate E ПРИНЯТА: ACCGATEE9 = GO** (четвёртый круг). Эволюция: gatee6→ACCGATEE6 NO-GO (4 дефекта) → gatee7 (замок в IndexedDB) → ACCGATEE7 NO-GO → gatee8 → ACCGATEE8 NO-GO (мусор в журнале как законная запись ai-operation-ledger.ts:82-103; столкновение причинных ключей 0xd800/U+FFFD → потеря правки человека) → gatee9 → **ACCGATEE9 GO**: полная матрица мусора по ключу И токену пройдена, столкновение ключей закрыто (приёмщик искал свою пару — не нашёл), fail-closed при недоступном хранилище доказан. Отчёты: A1:/home/ubuntu/waves/GATEE9-REPORT.md, ACCGATEE9-REPORT.md. Вердикт приёмки: «флаг включать МОЖНО». Решение координатора: флаг ДЕРЖИМ ВЫКЛЮЧЕННЫМ до (1) браузерной приёмки глазами, (2) посадки на прод. Следующий шаг: посадка l64 вместе с остальным принятым, затем визуальная приёмка.

[28.08 14:10Z Фабл] Линия ролей (блокер эпика): ACCSHAPE2 = NO-GO — чужой userId доходит до поставщика ТРЕТИЙ раз за серию (ACCCOUNCIL → ACCSHAPE2), плюс tenant вне boundary и тихий catch. По правилу третьей находки заряжен РЕДИЗАЙН shapeguard3 (очередь 259): личность как опечатанный тип TrustedIdentity, конструируемый только на границе аутентификации; сырые userId/tenant-параметры удаляются из сигнатур — недоверенное становится непредставимым (компилятор+runtime-brand), матрица мусора один раз в конструкторе. Отчёты: ACCSHAPE2-REPORT.md, будет SHAPEGUARD3-REPORT.md.

[28.08 14:15Z Фабл] Поправка: предыдущая запись 14:10Z про ACCSHAPE2/роли попала сюда ошибочно — она относится к линии ролей, перенесена в WEB-108. Эпика движка это не касается; статус движка: Gate E принята (см. запись 12:10Z), Gate F = WEB-326.

[28.08 ~16:00Z Фабл] 📚 КАРТА ДОКУМЕНТОВ ЭПИКА ДВИЖКА (нулевой агент начинает отсюда):
- Лестница: Gate C (закрыта, этот эпик) → Gate D WEB-324 (посажена, l62) → Gate E (ПРИНЯТА 28.08: ACCGATEE9 GO; отчёты A1:GATEE9-REPORT.md, ACCGATEE9-REPORT.md; флаг ВЫКЛЮЧЕН до посадки+визуальной приёмки) → **Gate F WEB-326** (мультиюзеры/совместная работа; дизайн A1:wt-gate-f/GATE-F-DESIGN.md, отчёт A1:GATE-F-REPORT.md, commit d1b71160b6).
- Хвосты: WEB-221 большие документы (скорость принята, сохранность чинится: web221b→acc221b) · WEB-333 CodeMirror C09 (сдана, выключатель выключен) · WEB-304 потерянные волны (разобрано).
- Замороженный корпус: V2.1.2, 311 тестов — не трогается волнами.
- Урок 28.08: Gate F существовал без связи с эпиком → координатор его «не знал». Правило: каждый этап получает тикет и строку в эпике ДО старта волн.

[28.08 17:56Z Фабл] ⭐ ПОСАЖЕНО В l64 (прод arm64-l64-20260828T171744Z, sourceCommit 6508f013, artifact 8ff3f64c, подпись owner-prod-ed25519-6508f013-l64 проверена продом). paidReady=true/enforce_ready, fails=[], внешние пробы: / 307, /login 200, live-sha=6508f013. Откат: standalone-artifact.conf.bak-before-l64-20260828T175353Z. Ступень E на проде ВЫКЛЮЧЕННОЙ — включение после визуальной приёмки.

[BOARDTRIAGE] Последнее движение 28.08 17:56Z: l64 посажен и подписан, Gate E выключен до визуальной приёмки; Gate F и продуктовые хвосты ведутся отдельными тикетами WEB-326/333.

DISPATCH-20260910-3403
На 2026-09-10T21:38:23.260126+00:00: active; M4, волна 3403 engine-large-canary. Exact BASE 1ad52e16b784d3ae80a148fddae4d5a3ab4a89c4. Бриф прошёл brief-guard; входы SHA256 и наличие BASE проверены до постановки. Входы /Users/milamarty/waves/inputs/3403-engine-large-canary. Отчёт ожидается /Users/milamarty/waves/3403ENGINELARGECANARY-REPORT.md. Живой процесс модели подтверждён; возраст журнала 11 с. Source/подготовка и независимая проверка — в объёме брифа; это не посадка, не live/capacity GO и не окончательное закрытие security.

REFILL-2221-RESULTS-WEB-283
Снимок 2026-09-10T22:27:17.204978+00:00

Волна 3438 m4 gpt-5.6-luna: active (дочерний процесс подтверждён, журнал 3 с); exact BASE 5f8b953fe5d5b7227f806f3607f3359912abd711; inputs /Users/milamarty/waves/inputs/3438-acc-engine-canary
Новой посадки этим тиком нет. Evidence: nc-ops-scripts/refill-20260910-2221/.

THREAD-STATUS-2240 3438 bounded component GO; durable DocumentSession/CAS proof3456 и canary negative3461 на A2; runtime Gate E не включён.
Дети
Связи
Лента
2026-08-16T13:28:30Z · backup-opus
Создан эпик-тикет. Текущее: gatecpkg собирает R4-пакет ревизору на M4 (лог /tmp/gatecpkg.log); по посадке — проверка на распакованных байтах, салваж, доставка.
2026-08-16T14:20:43Z · backup-opus
16.08 ~15:55: волна gatecpkg села — пакет R4 собран, но МОЙ прогон верификатора из чужого каталога поймал два дефекта переносимости: git bundle verify без репо-контекста падает (need a repository), custody-указатель держал абсолютный путь M4 (класс дефекта из вердикта R3). Починено координатором: scratch-репо контекст; custody = env GATEC_CUSTODY_BUNDLE → путь → соседи пакета → честный SKIP-EXTERNAL (бандл 612МБ вне канала, sha 39746ee6 закреплён). Три прогона: с бандлом 7/7, без — SKIP rc=0. Receipt/отчёт регенерированы, суммы пересчитаны. ДОСТАВЛЕНО ревизору: GPTPRO-GATEC-LEGS-8-9-R4-20260816.zip digest 349939a92cec2938ac7aa1d6100f844b6a3ea2ef494f0b116bd153969979efeb (105571086 байт, пломба сошлась на обоих концах).
2026-08-16T14:54:03Z · backup-opus
16.08 ~16:05: вердикт R4 — diagnostic acceptance GO, формальный Gate C NO-GO. Пломба 349939a9 сошлась, оба патча реконструируют дерево, leg 8 6/6 на доступных клетках. Главный блокер: backward/pre-save фиксы живы в изоляции, но НЕ в полном последовательном leg-9 прогоне того же BUILD_ID (cross-cell state/timing). 7 требований R5: стабильный полный прогон x3 без исключения неудач; генератор матрицы видит все receipts/конфликты/хронологию edit-save; закрыть 4 FAIL + 5 NOT-RUN; custody bundle или подписанная attestation; exact артефакты; fail-closed verifier (custody-скип = отдельный ненулевой код). Вердикт: ревизор/вердикты/GATEC-R4-VERDICT-20260816.md. Волна gatec5 запущена (пп.1-3).
2026-08-16T16:19:13Z · backup-opus
16.08 ~17:25: gatec5 села, салваж 0eeb1ebd. Корни нестабильности R4 доказаны репро: (1) протечка realtime-комнат между клетками (process-global rooms не чистит документ — изолированная WebKit-клетка PASS 84b, та же клетка третьей в последовательности FAIL 140b/ops=0), (2) чтение Selection после браузерной нормализации. Фиксы: namespace per runId+surface (сервер один, 0 рестартов), selection до normalization + фикс EditorModal. 3 полных последовательных прогона зелёные на Chrome/Firefox/WebKit. Новый строгий генератор derive-matrix.py: все receipts BUILD_ID, конфликты как blocker, хронология edit<save, fail-closed CLOSED — юнит-тесты 4/4. Прогон координатора: TS 0 fails, Py 4/4. NO-GO волны = честность генератора (ранний красный receipt того же билда учтён). Дальше: пересборка → чистые 3x прогоны → пакет R5 с custody/exact-артефактами/fail-closed verifier.
2026-08-16T19:17:34Z · backup-opus
16.08 ~23:20: gatec6 (linux/arm64 эпоха) села с честным NO-GO 0/3: строгая матрица работает как задумано. Ценное: exact-byte артефакты ON/OFF собраны (tar.zst + пофайловые манифесты, 254М каждый), клиент-байт пруф флага, вся машинерия чистой эпохи готова. Границы платформы: Chrome-клетка NOT-RUN — validator продуктовой identity ожидает macOS app bundle (Playwright bare binary не доказательство); Firefox/WebKit — setup FAIL до редактора (фикстурная карточка не становится видимой за 90с на linux, воспроизводится на OFF и ON — бутстрап/гидрация, диагноз без поспешных фиксов). ВЫВОД: финальная чистая эпоха R5 пойдёт на M4/darwin (там gatec5 уже дала 3x зелёных последовательных), с переиспользованием строгой машинерии gatec6; linux-находки задокументированы отдельной платформенной клеткой. gatec7 в очередь на слот M4.
2026-09-02T21:26:23.618Z · Fable-M1
Состояние на 02.09 для нулевого контекста

Лестница гейтов DocumentSession (этот эпик = Gate C): Gate A контракт ✅ (06.08) → Gate B библиотека ✅ (F01–F06, 311+135 тестов) → Gate C legacy shadow ✅ ЗАКРЫТ 23.08 (пакет R22G-F4, вердикт аудита GO, WEB-089 CLOSED-VERIFIED) → Gate D controlled writer посажен l62 (WEB-324) → Gate E mutating AI ПРИНЯТА 28.08 (ACCGATEE9 GO, 4-й круг) → Gate F collab = W1-дизайн d1b71160b6, NO-GO by design.

Спека ENGINE-GATEC-EPIC.md УСТАРЕЛА (16.08, «R4 собирается») — фактически линия давно на R22G-F4 GO.

Телеметрия Gate C (25.08, shadowrun5, 19167 записей): corruption=0 (движок ни разу не испортил контент), contentHash/historyDepth совпали 98%; остаток 2% = anchors(451)+dom-mutation(319), НЕ порча данных.

На проде l93 (02d032e4): GATED_WRITER=1, MUTATING_AI=1, product wiring=1 COHORT=all, c09bigdoc3/4/5. Owner 02.09 20:38: «включили — многое не работало; пропала панель форматирования (только «И»); примите и проверьте сами, работает ли абсолютно всё из эпика».

Открытые хвосты: WebKit clipboard NOT-RUN 3/3, нативный IME, render order, продукт E2E, 3 из 5 находок лега 9, аналитика-нули, белые экраны переходов, WEB-491 (панель форматирования), Gate F W2.

Сводная карта + чек-лист «работает абсолютно всё» (22 пункта) + открытые вопросы: board/specs/ENGINE-EPIC-STATE-20260902.md

Проверка идёт волной 1350-engineprodmatrix (Playwright A–I на проде). Связано: WEB-491 (новый), WEB-333 (C09).
2026-09-02T22:09:45.014Z · Fable
[A1 22:55 Фабл] МАТРИЦА ДВИЖКА НА ПРОДЕ l93 (волна 1350, отчёт A1 /home/ubuntu/waves/ENGINEPRODMATRIX-REPORT.md, 73 улики в /home/ubuntu/waves/evidence/engineprod/): ответ owner-у — НЕТ, всё из эпика не работает. PASS: legacy-редакторы, малый wiki-пайплайн, C08 legacy-HTML viewer (с ограничением). FAIL/BLOCKED: A маршрутизация (все доки → legacy/c02-fallback hydration=failed, большие → cm6 pending без текста); B тулбар (нет H/ссылок/кода, C09 прячет) → WEB-491 волна 1387; C C06 save ack раньше записи → WEB-495 волна 1386; D realtime C07 — 500 /api/realtime/socket (нет res.socket.server в standalone) → WEB-492 P0 волна 1383; E большие документы (PDF extraction застряла, HTML/TXT partial после 504) → P0 волна 1384; G gated writer/mutating AI выключены в бандле (build-time флаги, сборка без них) → WEB-494 волна 1385 + флаги в build-env l94; H обзоры/wiki/NER на большом источнике BLOCKED из-за E; I 20×500 + 504. Следующая матрица — после посадки фиксов (l94/l95).
2026-09-02T22:16:49.060Z · Fable-M1
Спека обновлена: `/Users/poolpooly/Projects/nc-agent-ops/board/specs/ENGINE-GATEC-EPIC.md` (R22E/R22G-F4, l92/l93, прод-матрица 02.09 и cleanroom ↔ prod).
2026-09-06T04:04:57.248Z · coordinator
[06.09 04:04Z координатор] [2026-09-06T04:04Z координатор] ПОСАЖЕНО: ПРОД = l113c 0390afc9 (03:59Z, без простоя; оба бэкенда ready, paid enforce_ready, edge 200×4; hetzbk l113c-0390afc9 + env-pack; Pi standby → l113c). В составе: WEB-505 3bb21db4 (окно цитирования), WEB-497 a1b3f9fd (судья), WEB-495/465 revive-бюджет (сквош 75ac1e21), WEB-564/566 Apple origin-lock 7c46b0ee, WEB-530 f7a427bd(+db551088), WEB-562 2daaf3db, WEB-556 1666dfb2, WEB-549/551 5d497bfe. Откат = l113b 02812b90 (RUN l113b-02812b90, REL arm64-l113b-20260906T003405Z). Артефакт me2-standalone-linux-arm64-0390afc9-20260906T035404Z sha 97076030…
2026-09-06T09:10:07.438Z · coordinator
[06.09 09:10Z координатор] [2026-09-06T09:09Z координатор] ПОСАЖЕНО: ПРОД = l113d 4c73d845 (09:03Z, без простоя; оба бэкенда ready, paid enforce_ready, edge 200×4; миграции применены (184 в репо), hetzbk l113d-4c73d845 + env-pack, Pi standby → l113d). В составе (21 коммит над l113c): большой PDF — персист чанков короткими idempotent-транзакциями (WEB-086/496/467), периметр stream-safe (WEB-495/093), WEB-554 отзыв тетради, WEB-540 translation claim, WEB-543 customer guard, WEB-559 binary adapter, WEB-567 issuer authority, WEB-558 facebook attempt, WEB-491 mobile cold-start, WEB-370 пакет телефонии (репо-часть). Откат = l113c 0390afc9. На проде после посадки: revive PDF cmtkm80jo… → running (персист прошёл 5-с барьер — наблюдаю до done); big-test всё ещё упирается в бюджет (identity v4 — волна 2229).
2026-09-06T10:21:10.521Z · coordinator
[06.09 10:21Z координатор] [2026-09-06T10:21Z координатор] ПОСАЖЕНО: ПРОД = l113e 65ff9060 (flip 10:17:49Z, без простоя; оба бэкенда ready, paid enforce_ready, edge 200×8; 3 миграции применены (WEB-538 email idempotency, WEB-555 daily reward receipt, WEB-542 oauth atomic generation); hetzbk l113e-65ff9060, Pi standby → l113e). Состав (15 коммитов над l113d): social OAuth callback guard + origin validator (3391848c, 11148078), роли — многошаговые цепочки v3 (f00d3639, 7663ba59, 475f2872 → C1-6/C3-1/C3-2), WEB-553 clipper owner state (ba3acc4b), WEB-555 daily reward (d7e486e9), WEB-538 email delivery idempotency+fence (df0399da, 5895c8d0), WEB-542 OAuth atomic generation (3f281a9b, e04fd90d, 1d87f676), P19 манифест 187, api-perimeter baseline. Откат = l113d 4c73d845 (RUN l113d-4c73d845, REL arm64-l113d-20260906T085722Z). Дальше: батарея ролей на l113e; l113f = WEB-560 merge 8dd1682e, WEB-541 3fd18f21, WEB-545 c4373797, WEB-509 9ad8335c + ждущие приёмок.
2026-09-06T11:10:21.280Z · coordinator
[06.09 11:10Z координатор] [2026-09-06T11:10Z координатор] 🔴 P0 НА ПРОДЕ (найдено волной 2278c по живым receipts и подтверждено SQL): DocumentChunk с sourceContentRevision IS NULL (QUARANTINE, скрыты для retrieval через sourceChunkFreshnessSql, src/lib/rag/sourceReadPolicyServer.ts:68-73) = 54 728 из 104 761 чанков прода (52%). Это чанки, чей текст не дословная подстрока источника (legacy splitter, 
 vs 

). Код l113e чинит splitter только для новых индексаций (46ee733d, chunking.ts:376-430); существующие чанки никто не чинит → у пользователей больше половины корпуса невидима в поиске/чате. Нужен repair: (а) для каждого источника с quarantine-строками — пересчитать чанки прод-чанкером (chunks-only reindex, без платных embeddings, если текст совпал — или с re-embedding при изменении границ), батчами, идемпотентно, с чекпоинтами; (б) метрика/алерт quarantined>0; (в) completeness receipt должен это видеть. Волна 2278c продолжает (repair-инструмент + судья + receipt).
2026-09-06T12:11:05.148Z · coordinator
[06.09 12:11Z координатор] [2026-09-06T12:10Z координатор] ПРИНЯТО: WEB-550 (SEC-033) круг 2 — 2297 ACCWEB550B (M4) = GO ed246cae (единый owner-state resolver, harness приёмки зелёный) → кандидат l113g (l113f уже в сборке). WEB-531 слияние на кандидат = GO e8c97f1f (2302) → l113g. Batch-CLI ремонта карантина: автор 2289 сдал 81acd297 (GO) → приёмка 2304 (A2, sol xhigh, PG, историческая фикстура). WEB-568 круг 2: автор 2303 сдал faf26ab9 (GO) → приёмка 2305 (M4).
2026-09-06T12:38:35.500Z · coordinator
[06.09 12:38Z координатор] [2026-09-06T12:38Z координатор] ПРИНЯТО: revive-identity 5 + WEB-499 (2308 ACCWEB499B, sol xhigh, PG) = GO 42b61743 → кандидат l113g. WEB-552 (SEC-035) круг 3 (2312 ACCWEB552C, M4) = GO ecca7846 → l113g. Роли круг 2 (2310) = NO-GO d4e3ea82: ремонт функционально верен (repaired=3/refused=0, факты, embeddings переиспользованы), блокер — гонка с конкурентным обновлением Source → круг 3 = 2313-roleschains3 (claude-opus, compare-and-swap по contentRevision + общий модуль с CLI). Backfill-CLI (2304) = NO-GO 81acd297: отказывает историческим Source по contentHash — чинится в 2313 общим модулем.
2026-09-06T12:43:05.509Z · coordinator
[06.09 12:43Z координатор] [2026-09-06T12:42Z координатор] ПОСАЖЕНО: ПРОД = l113f 221e8f39 (flip 12:39:47Z, без простоя; оба бэкенда ready, paid enforce_ready, edge 200×8; миграций новых нет (187/192); hetzbk l113f-221e8f39 + env-pack, Pi standby → l113f). Состав (15 коммитов над l113e): роли C5-C детерминированный отказ на прямом отрицании предиката (9fdfd6fe, 86afe601, 3ad54814, 59d4f3ee), WEB-541 SEC-024 retention contract (ebecd7f2, 3fd18f21), WEB-545 SEC-028 lighthouse headers (c4373797), WEB-509 gateway install (9ad8335c, репо-копия), WEB-463 barge-in + VAD env (0d7b50ee, 44ea7cea), WEB-542 rate-limit на client-account-generation (4891645b), WEB-508 SIP reload (8c76aa7d, b93d862f, репо-копия), WEB-506 куки-баннер (fc462e1d), периметр 500/embed (5837dd0f). Откат = l113e 65ff9060 (RUN l113e-65ff9060, REL arm64-l113e-20260906T101257Z). Снято с линии: WEB-560 merge (Prisma при импорте валил сборку → фикс 2309 → l113g). l113g: WEB-550 ed246cae, WEB-531 merge e8c97f1f, WEB-568 faf26ab9, revive5+499 42b61743, WEB-552 ecca7846 + ждущие: big-PDF r3, roles r3, backfill, 560 fix. Хост-синк SIP (508/509/463) — отдельное окно.
2026-09-06T13:05:11.142Z · coordinator
[06.09 13:05Z координатор] [2026-09-06T13:05Z координатор] Роли круг 3: автор 2313 (claude-opus) сдал 9d59aba3 (GO) — compare-and-swap по contentRevision, общий модуль ремонта для моста и batch-CLI → приёмка 2318-accroleschains3 (A2, sol xhigh, PG: фикстура 2286 + гонка 2310 + репро CLI 2304).
2026-09-06T13:17:11.434Z · coordinator
[06.09 13:17Z координатор] [2026-09-06T13:15Z координатор] ПОСАЖЕНО: ПРОД = l113g 4c322c46 (flip 13:14:18Z, без простоя; оба бэкенда ready, paid enforce_ready, edge 200×8; миграция WEB-550 file_link_lifecycle применена (188/193); hetzbk l113g-4c322c46 + env-pack, Pi standby → l113g). Состав (20 коммитов над l113f): большой PDF — финализация 3 круга (3c6a6f86, 76dcb114, 7779df11: короткая идемпотентная tx, hook вне tx, no-indexable-chunks для документов без текста), revive-identity 5 + WEB-499 doc_ner identity (a958df4b…42b61743), WEB-531 SEC-014 3 круга (ca35fbeb, ad7c0cfd, e8c97f1f — слияние), WEB-568 SEC-046 (84dce358, faf26ab9), WEB-550 SEC-033 (819da84e, ed246cae), WEB-552 SEC-035 (9d47fdf4, ecca7846), манифесты (188 миграций). Откат = l113f 221e8f39 (RUN l113f-221e8f39, REL arm64-l113f-20260906T123500Z). Дальше: revive документа cmtkm80jo… по инструкции приёмки; l113h = roles r3 (приёмка), WEB-560 build-fix (приёмка), WEB-507 8b155fc1.
2026-09-06T13:47:04.787Z · coordinator
[06.09 13:47Z координатор] [2026-09-06T13:46Z координатор] Роли круг 4: автор 2321 (claude-opus) сдал c7e9f946 (GO) — DB-side lock/statement deadline, refused=lock-busy без ожидания → приёмка 2323-accroleschains4 (A2, sol xhigh, PG 16: гонка с row lock 15 с + всё зелёное из 2318 + замеры + runbook для прода).
2026-09-06T15:05:31.387Z · coordinator
[06.09 15:05Z координатор] [2026-09-06T15:05Z координатор] Роли круг 5 (2332, claude-opus) = NO-GO по измеренному структурному пределу: батчи staging + единственное переключение реализованы (max tx 1.056 с, resume без дублей), но переключение привязки на стороне чанков стоит ~2.4 мс/строка (широкая строка с embedding): 10 000 строк = 22–30 с в одной tx, разбить нельзя (partial pages). Решение: (а) круг 5b = admission-порог ≤2000 чанков (переключение ≤5 с) — большинство карантинных документов чинится сейчас, крупные = refused=too-large; (б) круг 6 = поколение чанков (Source.currentChunkGeneration + DocumentChunk.generation, публикация = одна строка Source) — additive миграция, O(1) переключение. Обе волны на claude-opus (2350, 2351).
2026-09-06T15:05:53.324Z · coordinator
[06.09 15:05Z координатор] [2026-09-06T15:05Z координатор] Распределение карантина на проде (SQL 15:08Z): ≤500 чанков — 1232 док. (34 355 строк); 501–2000 — 9 док. (8 223); 2001–5000 — 4 док. (12 150); >5000 — 0. Порог 2000 (круг 5b) покрывает 1241 из 1245 документов; 4 крупных — круг 6 (generation). Файл для волн: /home/ubuntu/waves/inputs/roles-l113e/quarantine-buckets.md (A2).
2026-09-08T02:28:17.818Z · coordinator
[08.09 02:28Z координатор] СРОЧНО: ПОТЕРЯ ТЕКСТА ПОЛЬЗОВАТЕЛЯ ЧЕРЕЗ ПУТЬ СПАСЕНИЯ РАБОТЫ.

Найдено волной 2698 при анализе потолка больших документов. Отчёт ENGINEW4-ANALYSIS-REPORT.md, первая строка URGENT_FINDING=RESCUE_DOWNLOAD_CAN_EXPORT_STALE_OR_EMPTY_TEXT.

Сценарий: пользователь работает с большим документом, сохранение отказывает по потолку, пользователь жмёт «скачать», чтобы спасти работу, и получает либо ПУСТОЙ файл, либо СТАРУЮ версию до своих правок. Единственный путь спасения работы сам её и теряет, причём молча. Это опаснее самого потолка: отказ сохранения виден, тихая подмена содержимого — нет.

Установленные места:
- EditorModal.tsx:4387-4399 — на изменении Hybrid обновляются только ссылки dirty и version, полный content НЕ обновляется.
- EditorModal.tsx:8247-8260 — в Download передаётся именно content; EditorModal.tsx:12663 подключает обработчик к общему заголовку. Отсюда экспорт после правок отдаёт исходный сохранённый текст, а не живой снимок.
- EditorModal.tsx:3240-3249 — для крупных документов, принадлежащих продукту, старт намеренно с contentStr пустой строкой; точный текст живёт отдельно (:4023-4050) и попадает в legacy mirror только ПОСЛЕ успешной записи (:4082-4095). До первого успешного сохранения Download отдаёт пустоту.
- Черновика восстановления документа нет: в редакторском пути отсутствуют beforeunload, pagehide, sendBeacon и document-draft. Есть только локальное хранилище истории чата. После аварийной перезагрузки или закрытия вкладки живая версия не имеет надёжного пути спасения.
Сама модалка при отказе сохранения текст не уничтожает: dirty-флаг не сбрасывается, явный Save/Close возвращает ошибку. Опасен именно экспорт.

Запущена волна 2704: Download обязан отдавать живой снимок редактора, а при его недоступности ОТКАЗАТЬ с внятным сообщением, но не отдавать пустое или старое. RED-тесты на оба случая. Черновик восстановления после закрытия вкладки вынесен в отдельную работу и в эту волну не входит.

ОТДЕЛЬНО — РЕШЕНИЕ ПО ПОТОЛКУ.
Потолок стоит в src/lib/documents/documentLimits.ts:10-11, env DOCUMENT_MAX_UTF16_UNITS, значение по умолчанию 16 000 000. Производный потолок загрузки DOCUMENT_MAX_UPLOAD_BYTES = DOCUMENT_MAX_UTF16_UNITS * 3 (:36-41), то есть 48 000 000 байт UTF-8 при значении по умолчанию — это не отдельный лимит. Отказ в :52-62.
Замерено: документ на 20 000 000 UTF-16 (30 833 329 байт UTF-8) ОТКРЫВАЕТСЯ и редактируется — first text 44.61 мс, edit-ready 425.17 мс, 306 чанков по 64 КиБ, 81 DOM-узел — но сохранение отказывается за 70.10 мс. Читать можем, писать нет.
Рекомендация волны: чанковое точное сохранение (exact chunk manifest с total UTF-16/UTF-8, hash, revision/CAS и порядком, resumable запись, атомарная публикация). Причина: чтение, viewport CM6 и точная живая модель на 20M уже доказаны работающими; несовместима только запись одной цельной версией. Запрет редактирования честно убрал бы риск, но закрепил бы разрыв между «редактор открыл и дал работать» и «работу нельзя сохранить».
Последовательность: сначала протокол манифеста и чанков с атомарной публикацией и CAS, затем миграция C09/realtime, и только потом разрешать редактирование выше 16M. До завершения этой работы текущий редактируемый маршрут на 20M поддерживаемым считать нельзя.

KNOWN ISSUES / ТРАБЛШУТИНГ
Симптом: скачанный файл пуст или содержит версию до правок.
Проверка: внести правки без сохранения, нажать скачать, сравнить с содержимым редактора.
Причина: Download берёт поле content, которое при Hybrid-правках не обновляется, а для крупных документов до первого сохранения пусто (ссылки выше).
Лечение: брать живой снимок из того же источника истины, что и сохранение; при недоступности — отказ с сообщением, никогда не пустой файл.
2026-09-08T08:15:17.929Z · coordinator
[08.09 08:15Z координатор] 08.09: ОБЩИЙ КОРЕНЬ ЧЕТЫРЁХ НАХОДОК ПОТЕРИ ДАННЫХ УСТАНОВЛЕН. Читать целиком — это про устройство, а не про отдельный баг.

=== ЧЕТЫРЕ СИМПТОМА, найденные за ночь ===
1. Сохранение отказывает по потолку, пользователь жмёт «скачать» чтобы спасти работу — и получает ПУСТОЙ файл или версию ДО правок. Молча.
   Места: EditorModal.tsx:4387-4399 (на изменении Hybrid обновляются только ссылки dirty и version, полный content НЕ обновляется); :8247-8260 (в Download передаётся именно content); :12663 (обработчик подключён к общему заголовку); :3240-3249 (для больших product-owned документов старт намеренно с пустой contentStr); :4023-4050 (точный текст живёт отдельно); :4082-4095 (в legacy mirror попадает только ПОСЛЕ успешной записи).
2. Аварийный выключатель переводит открытый документ на запасной путь — несохранённая работа исчезает. Запасной путь строится из plainContent.
3. Двое пишущих: сохранивший вторым МОЛЧА затирает первого, первый не узнаёт.
4. Запись ИИ ОБХОДИТ защиту от затирания: ручной путь через DocumentSession имеет Source FOR UPDATE и CAS, а правка ассистента идёт в legacy DOM → updateDocument без ожидаемой версии → безусловное обновление строк. То есть пользователя защитили от пользователя, но не от ассистента.

=== КОРЕНЬ ===
Разведка зеркала (ENGINE-MIRROR-SCOPE-REPORT.md): VERDICT содержит THREE_FINDINGS_SHARE_SPLIT-AUTH. Все симптомы — следствия раздвоения источника истины: живой текст редактора и его сохранённое представление живут порознь, и разные потребители читают то одно, то другое.
Рекомендация: вариант «б» — оставить зеркала как проекции, но ввести revisioned consistency contract. Удаление зеркала сломает fallback, RAG и legacy-поверхности; ограничение потребителей неприемлемо для активного редактора, потому что именно устаревшие и пустые чтения породили находки.

=== ЧТО СДЕЛАНО ===
Симптом 1: коммит 07257c3ef09322a6aca8730ac9f5330c77581d25 (экспорт живого снимка через DocumentSessionProductSurface.currentSourceText() / HybridLargeDocumentEditor.getText() / синхронный contentRef) + b5526fb8b09df84efd37287cdcc5b405a02a3432 (отказ вместо пустого файла при непустом документе — дыру нашла приёмка круга 1). Оба посажены в l113r.
Симптом 2: коммит 3c96e9118cc6870498cd3148ea746b3dbd5ebc34 — версионированная граница записи, expectedContentRevision под Source FOR UPDATE до любой канонической записи, атомарный отказ stale-document. Приёмка GO. Посажен в l113r.
Симптом 3: закрыт тем же 3c96e9118.
Симптом 4: коммит b5d79e62a99646eb2a78c928b28200af947657f2 (editNoteInPlace под ту же границу) + AIWRITECAS-R2 (две ошибки типов, найденные приёмкой; требование — различающая проверка, а не глушение через as/any/!/@ts-ignore, потому что глушение спрятало бы ветку и вернуло ту же тихую потерю). Note-CAS вынесен отдельной работой честно.
Корень: ступенька MIRROR-1 — единый контракт живого снимка { text, documentId, revision, source: live|saved, availability } для ВСЕХ активных читателей (Find, chat, цитаты, инструменты редактора, fallback, экспорт), с правилом: при недоступном снимке явный отказ, НИКОГДА не тихая подстановка сохранённого зеркала. Коммит e010b05e36ea3e1d366f22b2ce906984dea6158d, на приёмке.

=== ПОТОЛОК 16M: РЕШЕНИЕ ВЛАДЕЛЬЦА ===
Замерено: документ на 20 000 000 UTF-16 (30 833 329 байт UTF-8) ОТКРЫВАЕТСЯ и редактируется — first text 44.61 мс, edit-ready 425.17 мс, 306 чанков по 64 КиБ, 81 DOM-узел — но сохранение отказывается за 70.10 мс. Читать можем, писать нет.
Потолок: src/lib/documents/documentLimits.ts:10-11, env DOCUMENT_MAX_UTF16_UNITS, по умолчанию 16 000 000; производный DOCUMENT_MAX_UPLOAD_BYTES = ×3 (:36-41); отказ в :52-62.
Владелец 08.09 06:24Z делегировал решение координатору. РЕШЕНИЕ: чанковое точное сохранение, а НЕ запрет редактирования. Обоснование: редактор уже открывает и держит документ, ломается только запись; запрещать работающее значит закрепить разрыв между «редактор дал работать» и «работу нельзя сохранить».
Проект разбит волной 2749 (CHUNKED-SAVE-DESIGN): протокол манифеста чанков, возобновляемость, атомарная публикация на существующем CAS, совместимость с документами до 16M, порядок волн.

=== АВАРИЙНЫЙ ВЫКЛЮЧАТЕЛЬ ===
ENGINEW3-REPORT: EMERGENCY_SWITCH=YES_FOR_NEXT_OPEN_ONLY, ROLLBACK_DATA_LOSS=YES_POSSIBLE_FOR_UNSAVED_LIVE_PRODUCT_EDIT.
Выключатель есть: admin-настройка documentSession.productWiring.killSwitch в RuntimeConfig, читается через /api/feature-toggles, рестарт и новая сборка не нужны. Но действует только на СЛЕДУЮЩЕЕ открытие: EditorModal запрашивает тумблеры при смене ключа открытия, а не периодически (EditorModal.tsx:1134-1138, useFeatureToggle.ts:133-179).

KNOWN ISSUES / ТРАБЛШУТИНГ
Симптом: скачанный файл пуст или содержит версию до правок.
Проверка: внести правки без сохранения, нажать скачать, сравнить с содержимым редактора.
Причина: Download берёт поле content, которое при Hybrid-правках не обновляется, а для больших product-owned документов пусто до первого сохранения.
Лечение: брать живой снимок из того же источника истины, что и сохранение; при недоступности — отказ с сообщением, НИКОГДА не пустой файл.
Урок метода: увидев несколько потерь данных подряд в одном продукте, искать общий корень ДО того, как чинить симптомы по отдельности. Здесь четыре фикса вышли верными, но общая причина осталась бы жить.
2026-09-09T08:03:01.270Z · coordinator
[09.09 08:03Z координатор] ОБНОВЛЕНИЕ СОСТОЯНИЯ ЭПИКА — предыдущая сводка от 06.09 указывала прод l113h и три открытых пункта. С тех пор девять посадок.

**Прод сейчас: l114k, `24a8ffcbca114145f0c126c2282864d3fab94c9f`.** Откат l114j.

## По трём открытым пунктам из прежней сводки

Прежняя запись: «Открыто: Redis/Prisma FK 2344, publication tx >5s 2332, landing latency 2339.»

- **Redis/multinode — вооружено.** `MULTINODE_ENABLED=1`, Redis активен, на проде два живых бэкенда (127.0.0.1:3010 и 127.0.0.1:3012), оба `ready=true`, перед ними контроллер апстрима с таймером. Неготовый бэкенд выпадает из балансировки сам.
- **Задержка посадки — измерена и стала предметом отдельной защиты.** В линии появилась проверка `checks.background` в `/api/ready`, которая сравнивает релиз ВОРКЕРА с релизом веба; контроллер апстрима смотрит именно на неё. Из-за этого посадка теперь обязана переводить воркеры ПЕРВЫМИ, до веба, иначе оба бэкенда вылетают из балансировки. Порядок зашит в land-скрипт.
- **Publication tx и FK** — по этим двум отдельного подтверждения за ночь не было; считаю их по-прежнему открытыми и не записываю в закрытые.

## Что добавилось в контур docsession/realtime за ночь

**Две настоящие потери текста пользователя, найдены и починены** (волна 3175, посажено в l114j):
- `unsavedPreserved=false` — несохранённая правка, сделанная при разорванном соединении, не переживала перезагрузку страницы;
- `localEditCommitted=false` — правка, застрявшая в полёте на время разрыва, не допубликовывалась после восстановления связи, если сосед в это время закоммитил своё.

Обе найдены волной 3166 на настоящем Socket.IO с проигрыванием журнала после разрыва, обратной доставкой в управляемой петле и испорченным конвертом — то есть не на моках.

**Регрессионный тест приёмки** `tests/postqa/web99-l114c-postqa.test.ts` включает случай прерванного повтора выбранного контекста.

## Что открыто и почему эпик не закрывается

1. **Совместная работа двух пользователей не доказана до конца.** Волна 3166 написала, что полная проверка вдвоём в её контуре недоказуема; владелец справедливо возразил, что учётки мы заводим и раньше так делали. Он прав, я пересказала формулировку волны, не оспорив её — это мой прокол. Волна **3186** сейчас делает совместную правку ДВУМЯ настоящими учётками через настоящий транспорт: обе правки видны обоим, одновременная правка одного абзаца не теряет ни одну, отмена у первого не откатывает правку второго, плюс зеркало после обрыва и при обратном порядке доставки. Ей отдельно запрещено писать «нужен браузер» без поимённого списка того, что именно требует браузера.
2. **Publication tx >5 s и Prisma FK** — из прежней сводки, подтверждения закрытия нет.
3. **Продуктовые хвосты legs 1–9** — отдельной сверки за ночь не делала, статус прежний.

## Смежное, что стоит знать при работе с этим эпиком

- `/api/ready` теперь требует пульсы `webhookRetries` и `scheduledPosts`; при пропаже любого из них контроллер апстрима выкидывает ОБА бэкенда. Юнит `nc-a1-webhook-inbox-retry` две недели падал `200/CHDIR` на удалённом каталоге релиза l105 — починен drop-in-ом; `nc-a1-scheduled-posts` заведён с нуля.
- Устойчивый приём вебхуков (P16) включала 06:02Z и **откатила 06:43Z**: он переигрывал уже обработанные записи `WebhookDedupe`, входящие сообщения дублировались с тактом 60 секунд. Откат — снятие env-drop-in; сброса ключа в базе оказалось недостаточно.
2026-09-10T18:55:03.657Z · coordinator
BOARD-WASH-20260910:WAVE-3337
По поручению владельца 18:43Z назначена исполнительская волна 3337 (engine), Codex gpt-5.6-luna xhigh, NEO. Полная история карточки и база l115c 1ad52e16b доставлены, brief-guard и проверка Git-базы пройдены. Задача: проверить существующую сдачу, устранить остатки, передать бандл и доказательства. Финальная приёмка и посадка остаются за координатором. Запуск группы подтверждён в журнале диспетчера.
КАРТА ДОКУМЕНТОВ: ноут /Users/annakorin/nc-ops-scripts/board-wash-20260910/3337-wash-engine-brief.md; NEO /Users/limamarty/waves/inputs/board-wash-20260910/engine-tickets.json; ожидаемый отчёт /Users/limamarty/waves/3337WASHENGINE-REPORT.md. Правила обогащения: WEB-449.
2026-09-10T21:39:01.276Z · coordinator
DISPATCH-20260910-3403
На 2026-09-10T21:38:23.260126+00:00: active; M4, волна 3403 engine-large-canary. Exact BASE 1ad52e16b784d3ae80a148fddae4d5a3ab4a89c4. Бриф прошёл brief-guard; входы SHA256 и наличие BASE проверены до постановки. Входы /Users/milamarty/waves/inputs/3403-engine-large-canary. Отчёт ожидается /Users/milamarty/waves/3403ENGINELARGECANARY-REPORT.md. Живой процесс модели подтверждён; возраст журнала 11 с. Source/подготовка и независимая проверка — в объёме брифа; это не посадка, не live/capacity GO и не окончательное закрытие security.
2026-09-10T22:27:17.864Z · coordinator
REFILL-2221-RESULTS-WEB-283
Снимок 2026-09-10T22:27:17.204978+00:00

Волна 3438 m4 gpt-5.6-luna: active (дочерний процесс подтверждён, журнал 3 с); exact BASE 5f8b953fe5d5b7227f806f3607f3359912abd711; inputs /Users/milamarty/waves/inputs/3438-acc-engine-canary
Новой посадки этим тиком нет. Evidence: nc-ops-scripts/refill-20260910-2221/.
2026-09-10T22:53:37.965Z · coordinator
THREAD-STATUS-2240 3438 bounded component GO; durable DocumentSession/CAS proof3456 и canary negative3461 на A2; runtime Gate E не включён.
2026-09-12T22:17:55.123Z · coordinator
[12.09 22:17Z координатор] МОЙКА 12.09 (3568-wash-g3-editor-ui): ядро Gate C/D/E принято и посажено, но часть контура тёмная и три хвоста (публикация >5 с, Redis FK, леги 1–9) без свежего подтверждения. Текст карточки склеился в кашу из старых сводок — стоит переписать. KEEP.
Остаток: Publication tx >5 с (2332) — свежего подтверждения закрытия нет.; Redis-hit Prisma FK → 404/500 (2344) — свежего подтверждения закрытия нет.; Леги 1–9 продуктовые хвосты — отдельной сверки не было.; Runtime Gate E не включён.; body карточки — мусорная конкатенация старых сводок («прод l113h», спека 16.08 устарела) — переписать шапку.
Отчёт: /Users/milamarty/waves/3568WASH*-REPORT.md (M4), копия nc-ops-scripts/shift-20260912-resume/wash-20260912/collected/. Проверка по исходнику прода l115g (9c8a9762).
2026-09-12T22:55:35.111Z · coordinator
[12.09 22:55Z координатор] ОСВЕЖЕНИЕ ТЕКСТА 12.09 (волна 3577, DeepSeek на M4): тело карточки переписано (шапка переписана (была конкатенация старых сводок, «прод l113h»); лестница Gate A–F актуализирована; хвосты 2332/2344/леги 1–9 выделены в остаток). Старый текст сохранён координатором (/tmp/body-backup-WEB-283.md на M1, копия в nc-ops-scripts/shift-20260912-resume/3577/collected/). Отчёт /Users/milamarty/waves/3577BODYREFRESH-REPORT.md.
2026-09-13T07:37:30.937Z · coordinator
[13.09 07:37Z координатор] РАЗБОР 13.09 (волна 3620, DeepSeek): Ядро Gate C/D/E принято и посажено, но закрывать рано.
1. Хвост 2332 (публикация >5 с): код посажен (батч ≤64, staged flip O(1)), но свежего прогона нет — нужно гонять roleschains5/6 + sourceChunkWriterTransactionTimeout на реальном Postgres.
2. Хвост 2344 (Redis FK 404/500): session-turn теперь сначала ищет session → session_not_found, потом создаёт VoiceTurn, но свежего прогона нет.
3. Леги 1–9 не сверены отдельно по статусу accepted/landed/enabled.
4. Gate E посажен выключенным, runtime-флаг тёмный.
5. body карточки склеился в кашу из старых сводок — стоит переписать шапку.
Предлагаю переписать шапку и держать в review, пока 2332/2344 не подтверждены прогоном и Gate E не включён.
Остаток: Publication tx > 5 с (2332) — свежего подтверждения закрытия нет (код посажен, прогона не было).; Redis-hit Prisma FK → 404/500 (2344) — свежего подтверждения закрытия нет (код посажен, прогона не было).; Леги 1–9 продуктовые хвосты — отдельной сверки «принято↔посажено↔включено» не было.; Runtime Gate E не включён — часть контура тёмная.; body карточки — мусорная конкатенация старых сводок («прод l113h», спека 16.08 устарела) — переписать шапку.
Предложение: KEEP/review — ядро Gate C/D/E принято и посажено, но хвосты 2332/2344 без свежего подтверждения, леги 1–9 не сверены, Gate E тёмный, шапка карточки — каша.
Ссылки: src/lib/realtime/server.ts:371,1808,1832,3375-3394,3555; src/lib/realtime/documentSessionVersionedHub.ts:424-473; src/lib/document-session/codemirror6/versioned-realtime-port.ts:2,77,93,118-139; src/lib/realtime/multinodeConfig.ts:10-11,27-39; src/lib/rag/sourceChunkWriter.ts:124,748,810-864,885-888; src/lib/rag/chunkGeneration.ts:18-28,58-62; src/app/api/realtime/session-turn/route.ts:196-232,316-348; src/lib/document-session/ai-operation-ledger.ts:17-23,29-43; src/lib/document-session/gated-wr
Материалы волны: shift-20260912-resume/colM|colP/ (RESULT.md + спецификации). Статус не меняю — применяю по мере прогона.
2026-09-13T08:26:45.333Z · coordinator
[13.09 08:26Z координатор] ЗАМЕРЫ ПРОГНАНЫ (13.09, волна 3627 на исходнике прода l115i; волна умерла, не написав отчёт — ушла ждать фоновую задачу, — но 18 сырых выводов успела сложить; координатор их снял и сводит здесь. Evidence: /home/wave/waves/3627EDITORMEASURE-evidence/ на A1, копия в shift-20260912-resume/colG/).
Скорость на огромном документе (это и был главный незакрытый хвост):
• Первый текст на документе 3.2 млн символов — меньше 1 секунды, PASS; замерена и готовность к правке.
• Операции по всему документу укладываются в записанные бюджеты: plain-text 21.4 мс при бюджете 75, измерение 99.7 при 285, разрешение выделения 4.8 при 25, разрешение бинарного 2.4 при 25 — PASS по всем.
• Поиск с подсветкой: прыжок к совпадению 24.6 мс на 3.5 млн символов (54 куска).
• Сохранение большого документа: выборка около 400–440 мс.
• Тяжёлый воркер (WEB-221): ускорение в 39.3 раза против базовой линии; структура rope — медиана 0.031 мс.
Многопользовательская правка и публикация:
• multiuser step1 persistence — 2 из 2 PASS; ВАЖНО: отрицательный контроль слабый (проверка «без FOR UPDATE гонка проявится» сама не сработала) — это дефект теста, не продукта, но пока он такой, «правка вдвоём доказана» писать нельзя.
• realtime mirror multinode 1/1, url-based pg-тесты 3/3, two-process C07 1/1, таймаут записи чанков 2/2, roleschains5 batched publication 3/3, роут session-turn 13/13 — всё зелёное.
• roleschains6 (generation publication) — прогон не завершился до смерти волны, перезапущу.
Вывод: по скорости хвосты закрыты числами. Остались два: слабый отрицательный контроль многопользовательской правки и недогнанный roleschains6. Ставлю добивку.
2026-09-13T09:35:35.061Z · coordinator
[13.09 09:35Z координатор] ПОСЛЕДНИЙ ХВОСТ ЗАМЕРОВ ЗАКРЫТ (координатор прогнал сам, 13.09, длинный тест 12.5 минут на одноразовой PostgreSQL 16): roleschains6 — публикация поколения — 2 из 2 pass, 0 падений, 0 пропусков. В частности доказано: перепривязка ревизии со стороны источника работает за постоянное время (O(1)), а протокол публикации никогда не отдаёт смесь поколений — сторонний читатель всё время видит ровно одно целое поколение.
Почему гнала сама: волна 3636 в третий раз ушла в фоновое ожидание и была снята, успев сделать работу, но не написав отчёт. Сырой вывод: /home/wave/waves/roleschains6-coordinator.out (A1), копия в shift-20260912-resume/3636/collected/.
Итог по замерам трёх эпиков редактора: все хвосты закрыты числами — скорость на огромном документе, операции в бюджетах, поиск, тяжёлый воркер, правка вдвоём с настоящим отрицательным контролем, публикация поколения.
2026-09-13T10:37:39.797Z · coordinator
[13.09 10:37Z координатор] Мойка доски, волна 3651. RETURN. Лестница Gate A–E принята и посажена; хвосты 2332/2344 закрыты числами 13.09 (замеры 3627: roleschains5 3/3, session-turn 13/13, url-based pg 3/3, realtime multinode 1/1). Не хватает: сверки лег 1–9 «принято↔посажено↔включено» и формального вердикта 3456/3461. Остаток — бриф A.
2026-09-13T10:51:17.155Z · coordinator
[13.09 10:51Z координатор] Волна 3662. RETURN (сводка бриф A). Хвосты 2332/2344 закрыты числами (3627: roleschains5 3/3, session-turn 13/13, url-based pg 3/3, realtime multinode 1/1). Сверка лег 1–9 НЕ собрана — перечня лег в карточке нет (только Gate A–F + следы leg 8/9), сведено что известно в LEGS-TABLE.md. Вердикта 3456/3461 НЕТ (требуется прогон). Не закрыто.
2026-09-13T10:54:33.282Z · coordinator
[13.09 10:54Z координатор] Найдено при мойке: вердиктов, которых «нигде нет», на самом деле два, и оба GO — просто их никто не забрал с машины сборки.
- Долговечность правки документа через настоящий путь сохранения (волна 3456): одноразовая PostgreSQL 16 с векторным расширением, полный набор миграций, 2 прогона, 0 отказов, 0 пропусков, 3.88 секунды. Продуктовый код не менялся — добавлен только тест.
- Отрицательный контроль канарейки большого редактора (волна 3461): 3 прогона, 0 отказов, 0 пропусков.
Оба бандла втянуты в зеркало: refs/waves/3456 = f23d4075, refs/waves/3461 = 5b6045bb.
Честная оговорка: обе волны работали на дереве 8429f2d3, а прод сейчас l115j 133fe00c. Вердикт на старом дереве не является вердиктом на текущем, поэтому запущена волна 3670: перенести оба теста на текущее дерево, получить те же числа и доказать, что тесты умеют краснеть. После зелёного прогона последнее препятствие к закрытию этих эпиков снимается.
2026-09-13T11:13:48.657Z · coordinator
[13.09 11:13Z координатор] Перепрогон на ТЕКУЩЕЙ линии сделан, блокер снят (волна 3670, refs/waves/3670 = 333b54aa).
Оба принятых доказательства перенесены с дерева 8429f2d3 на прод-линию l115j и дали ту же форму. Долговечность правки: три прогона, в каждом 2 успеха, 0 отказов, 0 пропусков, 2.1-3.1 секунды. Канарейка большого редактора: три прогона, в каждом 3 успеха, 0 отказов, 0 пропусков.
Отдельно доказано, что тесты умеют краснеть. Намеренно испорченное ожидание в каждом: долговечность даёт 1 успех и 1 отказ, канарейка 2 успеха и 1 отказ. Зелёное без этого не принимается.
Условия прогона: своя одноразовая база на приватном сокете, полный набор из 202 миграций, векторное расширение, кластер снесён после прогона. Общая база не тронута. Продуктовый код не менялся — добавлены только тестовые файлы.
Честная оговорка: это уровень автотестов. Полный браузерный проход, который волна 3461 когда-то делала отдельным ручным скриптом, на текущем дереве не повторялся. Если для закрытия нужен и он — это отдельный прогон, поставлю следующим.
2026-09-15T15:17:51.353Z · coordinator
[15.09 15:17Z координатор] 4052 current-line large-editor browser post-QA = DONE. На точном l115o доказаны search/navigation, streaming save/reopen и точный readback большого документа в трёх независимых Chromium-прогонах, skips=0; негативный контроль красный, SHA manifest цел. Остатков по доступному телу эпика нет.
Воркер
не проверен wq-engine-session-durable-proof, wq-engine-canary-negative-final A2 движение в панели: неизвестно
Подключиться и смотреть/перехватить руками. Колесо мыши листает; клавишами — Ctrl-b затем [, выход из прокрутки q. Отсоединиться — Ctrl-b затем d:
Прочитать историю панели без подключения — листается и ищется (/ поиск, q выход), воркеру не помешает:
Обновлён
2026-09-15T15:17:55.669Z