WEB-415 · Дефект · — · web
P0 Ассистент НЕ ЧИТАЕТ документы: запрос со словом «назови» уходит в inventory-ветку до retrieval
Закрыт
P0 · горит
ведёт: —
Суть
КОРЕНЬ (ragdiag, живой прод 27.08): запрос ошибочно классифицируется как INVENTORY-запрос из-за слишком широкого матча голого слова «назови». После этого chatWithSources возвращает системный inventory-truth ДО запуска retrieval и LLM. Inventory по замыслу работает только с лёгкими полями (id/name/type/stats), поэтому тело документа и grounded-prompt в ответ не попадают. Наблюдаемый эффект: «Відповідаю по scope поточне відкрите джерело. Я бачу 1 документ… Ця відповідь ґрунтується на загальних знаннях і не підтверджена вашими документами». Это ровно то, что owner видел утром («Область поиска пуста», scope-only ответы) и что заблокировало ВСЮ проверку качества ролей (rolesqa2 остановилась на smoke). ВТОРАЯ, независимая проблема того же прогона: у QA-документа ОТСУТСТВУЕТ semantic index — станет блокирующей сразу после починки маршрутизации, если источник не переиндексировать.
Как воспроизвести
Прод nb.wool2.online, QA-учётка, выбран 1 txt-источник. Вопрос: «По источнику X назови контрольную версию и процитируй подтверждающую строку». Ответ: inventory-сводка вместо цитаты. HTTP 200 на всех запросах (транспорт не виноват).
Чем закрывается (приёмка)
(1) Классификатор inventory срабатывает ТОЛЬКО на явные инвентарные запросы (сколько документов, список файлов, типы), а не на «назови/покажи/процитируй X из документа». (2) Тест-таблица: >=20 формулировок, где половина — инвентарные, половина — контентные; ни одна контентная не уходит в inventory. (3) Регрессия: инвентарные запросы продолжают работать. (4) Живой прогон на проде: вопрос из repro возвращает grounded-ответ с цитатой. (5) Отдельно: переиндексация источников без semantic index + проверка, что после неё ответ grounded.
Доказательства
[2026-08-27 ~13:15Z] Заведён по находке ragdiag (отчёт A1:/home/ubuntu/waves/RAGDIAG-REPORT.md, живая репродукция + телеметрия). Блокирует: rolesqa2 (тест качества ролей), WEB-398 (проверка звонка в тетрадь по смыслу), любые grounded-сценарии owner.
[2026-08-27 ~18:05Z acc415c NO-GO — осталось 2 фразы из 15] web415c дал GO (четыре матрицы зелёные: авторская, ACC415, граничная ACC415B, собственная WEB415C; введено ЯВНОЕ правило «инвентарный = вопрос о составе и метаданных корпуса»). Приёмщик ACC415C построил СВОЮ матрицу из 15 новых формулировок (которых не было ни в одной прежней) — 13 верны, ДВЕ семантически инвентарные фразы ошибочно уходят в retrieval, что нарушает само правило. Сборку и тест ролей запускать нельзя. web415d диспатчнута: закрыть обе фразы без возврата исходного P0 и обратной ловушки; при необходимости уточнить ФОРМУЛИРОВКУ правила и привести код к ней (правило первично); матрицу ACC415C целиком внести в репозиторий как постоянный регрессионный тест; прогнать все ПЯТЬ матриц.
[2026-08-27 ~19:05Z web415e GO — 117/117, СМЕНА ПОДХОДА сработала] После ПЯТИ кругов латания классификатора (каждый круг приёмка строила новую матрицу из 15 формулировок и находила 2 новых промаха) подход изменён архитектурно: route стал ДИАГНОСТИЧЕСКОЙ информацией, класс ошибки «не та ветка» убран из пользовательского контракта. Новый контракт: чистый metadata/inventory short-path разрешён ТОЛЬКО для однозначного вопроса о составе корпуса без предметной темы; во всех остальных случаях пользователь получает И справку о составе, И содержание из retrieval с цитатами. Итог: 117/117 GREEN по шести накопленным матрицам (авторская, ACC415, ACC415B, WEB415C, ACC415C, ACC415D), критерий сменён с «в какую ветку ушёл запрос» на «получил ли пользователь нужное». acc415e диспатчнута — финальная приёмка: 20 СВОИХ новых формулировок, критерий ПОЛЬЗЫ, проверка что retrieval не запускается на однозначно инвентарных (цена) и не дублируется, поведение на пустом корпусе, запрет молчания (пр.10), матрицы должны лежать в репозитории как регрессионные тесты. При GO: сборка -> посадка -> ТЕСТ РОЛЕЙ (44 способности + 30 безопасности) -> счёт owner-у.
[2026-08-27 ~19:31Z acc415e NO-GO — И СНЯТИЕ СОБСТВЕННОЙ ЦИФРЫ 117/117]
ГЛАВНОЕ: приёмщик вскрыл, что 117/117 доказывают ПЛАН и ФОРМАТ, а НЕ пользу. Тест src/lib/chat/__tests__/documentInventoryWeb415.test.ts вызывает buildFixtureRetrievalEvidence(), который САМ создаёт fixture-цитату и строку answer; ни route, ни провайдер, ни retrieval не вызываются. Цифра, доложенная owner-у как доказательство починки, снята (Telegram 14316).
ЧЕТЫРЕ ЗАМЕЧАНИЯ (все блокирующие):
1) пустой ответ при пустом корпусе И пустом ответе провайдера — нарушение запрета молчания (пр.10);
2) chat-global не сообщает об отсутствии semantic index, но всё равно делает embedding и ДВА поиска — тратит деньги молча; при этом /api/sources/semantic-search уже умеет честный 409 missing-index (7/7);
3) 4 из 6 однозначных инвентарных формулировок приёмщика уходят в ПЛАТНЫЙ retrieval — grammar short-path надо расширить на формулировки №2/3/4/6 из таблицы отчёта;
4) role-policy wiring 63/65: rolePolicyEnforcementWiring.test.ts ждёт старую форму (allowedSourceIds.length>0, deliveredContent), кандидат даёт новую (hasRetrievableCorpus, deliveredContentWithInventoryOverview) — тесты отстали от контракта.
ЧТО ЗЕЛЁНОЕ: chat-global+profile 12/12; inventory/document suites 32/32; /api/sources/semantic-search 7/7 включая честный 409; inventoryScope 9/9; scoped tsc + eslint + git diff --check pass.
ОТЧЁТ: A1:/home/ubuntu/waves/ACC415E-REPORT.md (таблица 20 новых формулировок с фактическими планами). Клон приёмки: /home/ubuntu/waves/acc415e-web415.
ЗАПУЩЕНО: web415f (очередь A1 140-web415f-brief.md) — закрыть 4 замечания + ОБЯЗАТЕЛЬНО добавить runtime-тесты через реальный путь route+retrieval (провайдер мокается на уровне сети/SDK, но НЕ подменяется готовым ответом): непустой факт+цитата, гибрид содержание+каталог, счётчик лишних поисков. Ослабление или удаление role-тестов запрещено — обновлять честно, в новых терминах.
ПОСАДКА И ТЕСТ РОЛЕЙ НЕ ВЫПОЛНЯЛИСЬ (вердикт NO-GO). next build не запускался, прод не трогался.
WEB-415N: оба блокера закрыты в worktree `wt-web415f`. HMAC-контракт сохраняет
`web415l-v1`, key-id, text hash, model, model-version и vector hash и теперь
дополнительно подписывает `documentId` и `chunkIndex`; полный перенос валидной
записи между документами отвергается. Active/previous secrets короче 32 UTF-8
байт не принимаются. Доказательства: embedding unit 4/4, proximity 7/7,
real-DB route 1/1; положительный факт/citation сохранён, короткие secrets дают
ноль embedding/SDK/network calls, ротация active/previous сохранена. `tsc`
scoped и `git diff --check` зелёные. `next build` не запускался. Source-read
policy, deletion policy и partial-corruption behavior не менялись.
[записал координатор: с A1 нет доступа к доске, блок перенесён из отчёта волны]
## 2026-08-28 ~12:15Z — взято в работу (координатор Фабл)
Волна `web415p`. Задача: воспроизвести на запросах «назови условия договора / участников / дату», найти точку выбора ветки (файл:строка) и **назвать природу дефекта**: если ветка выбирается по списку ключевых слов — это ловушка, расширять список запрещено, нужно устройство. Матрица запросов ru/uk/en: «назови…», «перечисли…», «что в документе…», «какие у меня документы», «сколько документов», смешанный. Обратная проверка: запрос про состав не должен уходить в чтение. Если ветка выбрана неверно — человек обязан это заметить, иначе добавить видимый признак.
[28.08 15:20Z Фабл] ACC415P = NO-GO: круг 2 РАСШИРИЛ СЛОВАРЬ вместо смены устройства — «назови документальное основание» всё ещё уходит в каталог файлов; плюс пустой результат поиска отдаётся как 409 «индекса нет» (отказ неотличим от отсутствия). Заряжен web415q (очередь 262) с запретом латания словаря: развилка НЕ лексическая, по умолчанию чтение содержимого, 409 только при физическом отсутствии индекса, тесты-провокации словами вне словарей. Отчёты: ACC415P-REPORT.md, будет WEB415Q-REPORT.md.
[28.08 17:00Z Фабл] web415q сдана — устройство СМЕНЕНО: лексический маршрутизатор (SOURCE_REFERENT_RE, stem-регулярки) УДАЛЁН; по умолчанию retrieval/чтение, inventory только по явной каталожной конструкции; «документальное/файловую/источниковедческий/договорную» читают содержимое, «покажи все файлы» остаётся каталогом. Заряжена приёмка acc415q (очередь 265): своя генерация провокаций, обратная сторона (каталог не сломан), 409 vs «нет совпадений». Отчёты: WEB415Q-REPORT.md, будет ACC415Q-REPORT.md.
[28.08 17:25Z Фабл] ACC415Q = NO-GO: устройство сменено верно, но остаточный путь — `documentation` совпадает как `document` (словоформа всё ещё решает в одном месте), кавычки превращают искомое содержимое в имя файла, нет доказанного content-default на случайных строках. Заряжен web415r (очередь 266): добить ВСЕ остаточные лексические пути + цитаты ищутся в содержимом. Отчёты: ACC415Q-REPORT.md, будет WEB415R-REPORT.md.
[28.08 20:15Z Фабл] ACC415R = NO-GO: новый класс — неизвестный термин + явный source scope + imperative-глагол в 5 формах не читается. Заряжен web415s (очередь 272): source scope → читать всегда. Отчёты: ACC415R-REPORT.md.
[28.08 17:45Z, влито] ACC415S NO-GO: кавычки-контент → каталог при searchCalls:0 (короткое замыкание до retrieval в /api/chat-global) → web415t (круг 6, опус). Отчёты: ACC415S-REPORT.md.
[28.08 19:45Z Фабл] ЭВОЛЮЦИЯ P0 (8 кругов, УСТРОЙСТВО менялось дважды): web415p (не расширять словарь) → ACC415P NO-GO (словарь всё же расширили: «документальное») → web415q СМЕНА УСТРОЙСТВА (лексический маршрутизатор УДАЛЁН, default=чтение) → ACC415Q NO-GO (documentation→document остаток; кавычки→имя файла) → web415r → ACC415R NO-GO (императивы+source scope) → web415s → ACC415S NO-GO (кавычки-контент → searchCalls:0, короткое замыкание до retrieval в /api/chat-global) → web415t → ACC415U NO-GO (auth().catch(()=>null) = АНОНИМНЫЙ УСПЕХ в auth-gated actions; обходы quote-mask) → web415v ИДЁТ. Отчёты: A1:WEB415[P-V]-REPORT.md, ACC415[P-U]-REPORT.md.
[28.08 круг 9 — WEB415V СДАН, приёмка ACC415W идёт]
Автор web415v (дерево /home/ubuntu/waves/wt-web415p, отчёт /home/ubuntu/waves/WEB415V-REPORT.md):
• Закрыт блокер ACC415U «анонимный успех»: auth-gated действия теперь возвращают типизированный AuthActionFailure (AUTH_UNAVAILABLE) вместо деградации в успешный анонимный результат.
• Quote-mask обходы закрыты структурно (не заплатками): Unicode, HTML-entities, двойное кодирование, висящие кавычки, смешение каталога и контента.
• Заявленные цифры: quote route 15/15, actions 5/5, inventory/realtime 72/72, global route 9/9; tsc web415p чистый, web415t сохранил baseline 68 диагностик; next build и прод не трогались.
Приёмка ACC415W запущена на OPUS (правило: security-приёмку не на OpenAI-моделях — sol/codex режут адверсариальные пробы модерацией, что сегодня подтвердилось на комнате). Дерево приёмки несёт состояние автора патчем от wt-web415p, база l64. Требования брифа: свои (не авторские) обходы, негативный тест обязателен, три вопроса (рестарт процесса / два контекста / отличимость мусора), и прямое указание: третья находка одного класса = менять устройство, а не латать (устройство здесь уже меняли дважды).
[28.08 ~19:00Z ACC415W (опус): NO-GO — половина принята, вторая требует СМЕНЫ УСТРОЙСТВА]
Отчёт: /home/ubuntu/waves/ACC415W-REPORT.md. Дерево приёмки несло состояние автора, sha 14 файлов совпали (actions.ts 27e18477, documentInventory.ts ecce5304, actionAuth.ts c035ae3a, chat-global/route.ts b729381e, semantic-search/route.ts c244d045, realtime/tooling.ts 7ccad773, telephony/groundedAnswer.ts b8524a09, sourceGrounding.ts d29ce002 + тесты).
ПРИНЯТО: anonymous-success закрыт ПО СУЩЕСТВУ — шесть действий переведены на typed getActionSession/AuthActionFailure; независимый прогон приёмщика 8 деградаций auth × 6 действий не дал ни одного анонимного успеха; негативный тест подтвердил валидность проб (ломаем fail-closed → пробы краснеют).
НЕ ПРИНЯТО: quote-mask routing. Устройство осталось ПЕРЕЧИСЛИМЫМ (allowlist пар кавычек + декодер сущностей в 2 прохода). Приёмщик сочинил СВОИ обходы и подтвердил ВОСЕМЬ новых, шесть — сквозь реальный route.POST с сигнатурой catalogAnswer=true, searchCalls=0. Автор объявлял этот класс «закрытым структурно».
ВЫВОД ПРИЁМЩИКА ДОСЛОВНО: за девять кругов класс воспроизводился многократно, латать очередную пару кавычек бесполезно — надо менять устройство. Чёрный список разделителей принципиально не закрывается: Unicode-кавычек и скобочных пар десятки, каждый круг добавляет названные прошлым ревьюером, следующий находит соседние.
УСТРОЙСТВО (§2.4 отчёта, взято в работу): (1) свойство-ориентированное распознавание — \p{Quotation_Mark}, \p{Ps}/\p{Pe} с парностью по Bidi_Paired_Bracket вместо перечня символов; (2) декод сущностей до ФИКС-ТОЧКИ вместо 2 проходов (закрывает n-кратное кодирование); (3) ГЛАВНОЕ — ИНВЕРСИЯ МОДЕЛИ: вместо «замаскируй все разделители» требовать для inventory/catalog позитивную, не-цитированную, верхнеуровневую императивную форму, совпадающую со ВСЕЙ инструкцией целиком; любой цитируемый/неоднозначный ввод по умолчанию уходит в retrieval. Позитивный список форм конечен — чёрный список кавычек нет.
Круг 10 запущен: WEB415W на опусе (/home/ubuntu/waves/briefs-opus/web415w-brief.md). Auth-часть, принятая приёмкой, переписыванию НЕ подлежит. Требуется: все 8 обходов приёмщика было/стало через реальный route.POST + 10 СВОИХ новых + список легитимных позитивных форм с прогоном + негативный тест.
[28.08 ~20:05Z WEB415X СДАН — починен ЖИВОЙ дефект прода (сохранение вставленного текста), приёмка ACC415Z заряжена]
Коммит 3228c093 в /home/ubuntu/waves/wt-web415x, отчёт /home/ubuntu/waves/WEB415X-REPORT.md.
Напомню происхождение: дефект пойман визуальной приёмкой EVISUAL2 на ЖИВОМ проде под настоящей QA-учёткой и подтверждён координатором в логах малинки (28.08 19:54:38Z): `Cannot persist invalid embedding provenance for chunk 1787943275110-0`, src/lib/rag/vectorStore.ts:200 — buildEmbeddingIntegrityRecord вернул null и уронил транзакцию. Загрузка файла работала, падал именно путь ручной вставки.
Заявлено автором: исправлены четыре пути (manual paste, file/import, dedup, update); provenance остаётся fail-closed; baseline manual test RED → после фикса GREEN, намеренная мутация RED; целевые тесты 73/73; scoped integrity tsc PASS.
Приёмка ACC415Z (очередь 305) с главным вопросом: не превратилась ли починка в ОСЛАБЛЕНИЕ. Требуется подсунуть действительно невалидные данные (пустой embedding, вектор неверной размерности, отсутствующая модель/версия, чужой documentId, отрицательный chunkIndex, NaN в векторе) — запись обязана быть отвергнута; фиктивная подставная провенанс-запись = блокер. Плюс проверка всех четырёх путей, своя матрица, негативный тест, три вопроса и отдельный ответ про риск для УЖЕ сохранённых данных.
[28.08 ~20:25Z ACC415Y: NO-GO, но с ВАЖНОЙ хорошей частью — класс обходов ЗАКРЫТ]
Отчёт: /home/ubuntu/waves/ACC415Y-REPORT.md.
★ КЛАСС ОБХОДОВ ЗАКРЫТ ПО СУЩЕСТВУ (дословно из вердикта): десятый круг закрывает 8/8 старых обходов приёмщика и 10/10 новых, включая no-delimiter, nested, bidi, invisible, entity и длинные последовательности (пример Y10: 24 повторяющихся пары тибетских ограничителей → catalogAnswer=false, searchCalls=1). Устройство подтверждено как свойство-ориентированное: PLAIN_SENTENCE_CHARS/DELIMITER_CHAR_SET (documentInventory.ts:483–485), Unicode-property класс (:489), QUOTED_SPAN_RE (:506–509), numeric entity через isDelimiterChar а не список кодов (:533–547), декод до стабилизации (:549–563), позитивный whole-instruction gate (:1871–1888, вызов :1907).
ПРИЧИНА NO-GO — регрессия на ЗАКОННОЙ стороне: из 19 авторских позитивных форм 18 дают catalogAnswer=true/searchCalls=0, а форма `how many documents do I have in "Work" notebook?` стала catalogAnswer=false, searchCalls=1. Не эффект моков: isInventoryQuery=false, resolveDocumentAnswerPlan().route="retrieval", buildInventoryAnswer ответа не строит. Корень: общий hasSubjectMatterCue (:2723–2731) считает ЛЮБУЮ цитату признаком содержательного запроса, тогда как здесь кавычки обрамляют ИМЯ ТЕТРАДИ. Красными стали tests/chat/documentInventory.test.ts:998–1001 и позитивный случай route-сьюты.
Смежное того же корня: строгое требование «никакого перечня кавычек в коде» выполнено НЕ полностью — вспомогательные QUOTED_TEXT_RE (:870) и QUOTE_ENTITY_RE/NAMED_QUOTE_ENTITIES (:516–531) остались; они не источник истины основного гейта, но QUOTED_TEXT_RE участвует в hasSubjectMatterCue и именно этот второй слой породил регрессию.
Корпус: 994 литерала × 3 режима = 2982 проверки, 0 исключений; относительно чистого f87f61a7 — 69 изменений классификации (57 закрытых прежних inventory-классификаций, 12 новых). Из 20 сьютов 12 полностью зелёных.
СЛЕДСТВИЕ ДЛЯ РОЛЕЙ: WEB-293 (44 способности) остаётся ЗАБЛОКИРОВАННОЙ — приёмщик ответил на этот вопрос прямо «НЕТ».
Круг 11 запущен: WEB415AA (очередь 308) — научить систему отличать кавычки вокруг ИМЕНИ СУЩНОСТИ КАТАЛОГА от кавычек вокруг СОДЕРЖИМОГО по устройству (не частный случай для слова notebook), привести hasSubjectMatterCue к тому же свойство-ориентированному распознаванию, и главное условие: ни один закрытый обход не должен открыться. Доказательства: 19/19 позитивных, 10 живых формулировок приёмщика, все 18 обходов заново, плюс свои 5 законных форм с именем в кавычках и 5 зеркальных с цитатой содержимого.
[28.08 ~20:35Z ACC415Z: NO-GO — целостность векторов подписывает вектор ЛЮБОЙ длины]
Отчёт: /home/ubuntu/waves/ACC415Z-REPORT.md.
БЛОКЕР: buildEmbeddingIntegrityRecord и isEmbeddingIntegrityValid подписывают и принимают вектор любой ненулевой длины. В src/lib/rag/embeddingIntegrity.ts:129-133 проверяются только пустота и конечность значений, проверки embedding.length === 1536 НЕТ. Доказательство приёмщика: «1535-dimensional vector: builderRecord=true, validatorRecord=true», при том что prisma/schema.prisma:1986 задаёт vector(1536). Вектор неверной размерности получает НАСТОЯЩУЮ HMAC-подпись; нулевой вектор подписывается и отбрасывается лишь позже проверками health/retrieval — контракт записи НЕ полностью fail-closed. Красный тест: src/lib/rag/__tests__/acc415z-adversarial.test.ts.
ОТДЕЛЬНО ОТМЕЧЕН РИСК ДЛЯ УЖЕ СОХРАНЁННЫХ ДАННЫХ: миграция 20260828100000_web415j_embedding_integrity добавляет nullable provenance, значит в базе могут быть строки без провенанса или с подписью вектора неверной размерности.
Круг запущен: WEB415AB (очередь 311) — размерность как обязательное условие подписи из ОДНОГО источника истины (не хардкод в двух местах), отказ нулевого вектора на входе, сохранение починки ручной вставки, матрица размерностей (1536/1535/1537/1/0/огромная), негативный тест, и обязательный раздел про судьбу уже сохранённых строк с планом (в проде ничего не менять).
---
## 2026-08-28 21:30Z — ACC415AC: GO по чтению документов (круг 11)
- Коммит eb4ffeac (wt-web415aa): maskQuotedSpans передаёт content-gate контекст вокруг литералов; hasSubjectMatterCue на общих spans, отдельного перечня пар кавычек нет.
- Приёмка /home/ubuntu/waves/ACC415AC-REPORT.md: пробы на реальном пути инвентаря (не фикстурах), контрпримеры с вложенными/смешанными кавычками, «назови» с цитатой и без. Законная форма починена, класс обходов остаётся закрыт.
- Следствие: блокировка WEB-293 (роли-способности) по этому P0 СНЯТА.
- Соседняя линия векторов (та же семья брифов web415*): ACC415AD NO-GO — см. свой тикет; на чтение документов не влияет.
- НЕ в l66 (сдано после слияния) — кандидат следующей посадки.
---
## 2026-08-29 04:15Z — ⚠️ принятый груз НЕ влился: столкновение контрактов, заряжен круг решения
При слиянии l67 волна L67MERGE обнаружила: принятый коммит eb4ffeac и УЖЕ ПОСАЖЕННЫЙ в l66 слой web415f по-разному переопределяют isInventoryQuery. После слияния documentInventoryWeb415.test.ts даёт 5/13 (на чистом l66 — 13/13). На чистом eb4ffeac кода web415f нет вовсе, и гейт возвращает false на четыре разговорные формы: «Hey, what docs've I got in here?», «Слушай, какие доки у меня уже загружены-то, а?», «Покажи all my файлы, плиз 🙃», «Сколько у меня ещё доков загружено в этом workspace?».
Волна НЕ стала примирять контракты (это меняло бы принятое поведение) — правильное решение; попытка сохранена в ветке l67-web415aa-attempt (960a886d), в l67 её нет. Отчёт: /home/ubuntu/waves/L67MERGE-REPORT.md.
Заряжен круг WEB415DEC (A1 queue/359): ОДИН контракт вместо двух — разговорные формы попадают в inventory; «назови»+цитата НЕ уходит в inventory мимо retrieval (исходный P0); оба набора тестов зелёные на итоговом коммите; предсуществующие падения embed/proxy назвать честно.
Статус тикета остаётся review (принято приёмкой), но ДОСТАВЛЕНО НЕ БУДЕТ, пока контракт не сведён — это отражено здесь, чтобы никто не считал линию закрытой.
---
## 2026-08-29 07:10Z — ACC415DEC: NO-GO по одному красному (контракт СВЕДЁН)
Главное сделано: единый контракт inventory собран, inventory-набор зелёный, исходный P0 закрыт (цитата с «назови» не уходит в inventory мимо retrieval). Приёмка отказала строго по правилу «любой красный — NO-GO»: цитатный набор 82/83, красный N10 — subordinate-фраза без разделителей.
Приёмка честно отделила предсуществующие падения: embed-helpers 42/47 одинаково на d6a00863 и на чистом l66 (не регрессия круга); summaryExport 10/11 — известный baseline CHAT-0377.
Круг WEB415DEC2 заряжен (queue/378): закрыть N10, не сломав ни одной зелёной формы; при конфликте правил — обосновать продуктово, а не «чтобы позеленело».
---
## 2026-08-29 07:25Z — круг 2: 83/83, финальная приёмка заряжена
WEB415DEC2 (коммит a823faf2): цитатный набор доведён до 83/83 (7/7 сьютов), N10 закрыт. Sentinel автора: retrieval даёт searchCalls=1, 19 позитивных catalog-форм — catalogAnswer=true и searchCalls=0.
⚠️ В брифе приёмки ACC415FIN (queue/379) отдельным пунктом: автор для route-контракта использовал ОТДЕЛЬНОЕ временное fixture-дерево с mock-only ответами inspectSemanticIndex и live ACL source row — приёмщик обязан проверить, что продуктовый код и assertions не менялись и эти моки не попали в принимаемый коммит (иначе «зелёное на фикстурах»).
---
## 2026-08-29 08:00Z — ✅ ACC415FIN: GO. Линия чтения документов ЗАКРЫТА
Финальная приёмка приняла коммит a823faf2: единый контракт inventory-гейта, оба набора зелёные (13 форм inventory + 83 цитатных), исходный P0 (цитата с «назови» не уходит в inventory мимо retrieval) закрыт, предсуществующие падения отделены от регрессий.
Линия готова к посадке — кандидат l68. После посадки проверить живым запросом на проде (запрос со словом «назови» + цитата → ответ из документа, а не из инвентаря).
[29.08 ЖИВАЯ ПРОВЕРКА ПРОДА l68, обычная не-админская учётка] Запрос со словом «назови» + просьба цитаты БОЛЬШЕ НЕ уходит в inventory: ассистент вернул точную фразу из документа («Human edit exact omega.»). Разговорный инвентарь («какие у меня есть документы») отвечает верно: 4 документа, все имена названы точно.
ОГОВОРКА 1: проверено только при Decision mode = Council: Off. При включённом Совете любой запрос падает (отдельный корень: ReferenceError channelModel, см. WEB-428).
ОГОВОРКА 2: ответ ЗАГРЯЗНЁН противоречивыми шаблонами — рядом с найденной цитатой вставлено «Nothing on this topic was found in the documents», а к верному инвентарю пришит ложный дисклеймер «This answer is based on general knowledge and is not confirmed by your documents». Сам дефект тикета закрыт, загрязнение — отдельная задача.
[29.08 ЗАГРЯЗНЕНИЕ ОТВЕТОВ: круг 1 bf39cc33, ACCANSWERCLEAN_VERDICT=NO-GO, круг 2 заряжен (очередь 455)]
ПРИНЯТО: инвентарный префикс убран там, где его не просили; отрицание «Nothing on this topic was found» больше не приклеивается к верно найденной цитате.
БЛОКЕРЫ:
1. ⚠️ Дисклеймер доверия ведёт себя ПО-РАЗНОМУ на двух путях. Для настоящего ответа из общих знаний без inline-маркера при наличии retrieval-кандидата: глобальный чат сначала обнуляет citations (src/app/api/chat-global/route.ts:1864-1882), затем видит markersRemoved=0 и дисклеймер НЕ добавляет; путь тетради на том же классе даёт citationsDroppedWithoutMarkers=true и дисклеймер ДОБАВЛЯЕТ. То есть глобальный чат молча выдаёт непроверенный ответ как проверенный — хуже исходного дефекта.
2. Очистка разметки не закрывает ЭКРАНИРОВАННЫЕ сущности — цитата с ними по-прежнему протекает.
3. Один вариант инвентаря в тетради всё ещё может выдать ложное «ничего не найдено».
4. Собственный wiring-тест коммита не проходит.
Круг 2 обязан свести признак «ответ подтверждён документами» к ОДНОЙ общей функции для обоих путей и приложить таблицу эквивалентности по классам ответа.
[2026-08-29 14:55Z] СУХОЙ ПРОГОН ПОДПИСАНИЯ НА РЕАЛЬНОЙ БАЗЕ: инструмент не может подписать ни одной строки. Бандл собран из принятого коммита 0b3be0c7 (esbuild, esm, sha 1b8d7a79effde0f8, доставлен на Pi с совпадением хеша), ключ подхватился (64 символа, id=v1), база подключилась. Отчёт /tmp/bf-report.json: scanned=500, validCandidates=0, signed=0, rejected=500, rejectedByReason={"missing-embedding-text-hash":500}. Замер по всей таблице DocumentChunk: всего 127441, есть вектор 127441, embeddingTextHash 0, embeddingModel 0, embeddingModelVersion 0, embeddingIntegrityHash 0 — пусты ВСЕ четыре служебных поля, а не только подпись. Инструмент по устройству подписывает лишь строки, где хеш текста уже проставлен, поэтому на реальных данных бесполезен. Класс дефекта — «зелёное на фикстурах ≠ польза»: приёмка ACCEMBSIGNBACK дала GO на строках, где метаданные были заполнены; корень — моё задание не требовало проверки против реального распределения данных. Восстановить поля задним числом технически можно (колонка content на месте: 127441 строк, 105 913 844 знака), но тогда подпись удостоверит непроверенное: если текст менялся после векторизации, поиск молча вернёт устаревшее под честной подписью. Оценка честной переиндексации: около 26,5 млн токенов, text-embedding-3-small — примерно 0.5 USD разово. Владельцу отправлен запрос на решение (переиндексация против реконструкции полей).
[2026-08-29 17:15Z] Инструменты переиндексации найдены в воркере l70: --missing-chunks-summary, --requeue-missing-chunks, --repair-missing-chunks. ВАЖНО для исполнения: прямой запуск воркера из оболочки координатора падает на server-only (This module cannot be imported from a Client Component module) — systemd запускает его иначе, поэтому при одобрении переиндексации запускать через системный юнит note-clone-source-indexing, а не вручную. Отдельно: --repair-missing-chunks НЕ решает нашу задачу, потому что у старых 127441 фрагментов чанки ЕСТЬ, отсутствуют только служебные поля (embeddingTextHash, embeddingModel, embeddingModelVersion, embeddingIntegrityHash) — режим «недостающих чанков» их не увидит. Значит честная переиндексация должна пересоздавать чанки, а не дополнять. Решение владельца по трате (~0.5 USD) ещё не получено.
Воркер
не привязан — привязать:
curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \
-d '{"issueId":"WEB-415","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-29T15:32:08.104Z