Improve search ranking and support empty reviews #61

Merged
agent merged 5 commits from fix/search-relevance-and-empty-reviews into main 2026-11-02 23:44:13 +00:00
Collaborator

Risk level: HIGH.

Changes

  • Apply dfs_query_then_fetch only to explicitly configured multi-index /search requests; single index and filters retain the default behavior.
  • Preserve full configured index scope in signed review snapshots for comma-separated scopes.
  • Allow signed empty-result reviews with a required overall comment; validate exact ranks/codes for non-empty results.
  • Add a narrowly scoped rental-term expansion while retaining the original query.

Evidence and limits

  • Full isolated benchmark: 7,500 unique queries at executable code SHA 1c7ddf2fcbd7c55920470e7ac52339fdab0366db, algorithm search-8; output SHA-256 fc02e22e5b3d612813ffc0bdaf9892bb16ee4c29af3e1b77f79e58a0a45c8ec1. Compared with baseline, order changed in 537 queries and top-1 in 103. These are ranking observations, not improvements or expert legal judgments. Six empty results remained empty.
  • Three current acts were evaluated only through a separate isolated local supplement. Production and the base index were not changed. Corpus completeness, licensing, full edition history, and legal relevance remain unverified.
  • The report and changelog follow-up is docs-only commit 849c19e2ab1805466c42419bcd4cff2d47882ed6; benchmark results are for executable SHA 1c7ddf2, not a runtime run of the docs commit.

Compatibility, security, and rollback

  • No database migration or schema change. HMAC, expiry validation, authentication, and existing non-empty review validation remain in place.
  • No production, index, VPS, Docker, or source-data changes. Rolling back the application restores the previous multi-index query mode; existing review rows remain readable.

Checks

  • Backend, Telegram, backup, deploy, guard, compilation, targeted checks, full isolated benchmark, and read-only runtime gates are documented in docs/product/search-relevance-findings-2026-11-03.md.
  • Current docs head 849c19e2ab1805466c42419bcd4cff2d47882ed6: Gitea CI run #696 passed in 2m12s; runner smoke #697 passed in 2s.
  • No merge or production deployment has been performed.
Risk level: HIGH. ## Changes - Apply `dfs_query_then_fetch` only to explicitly configured multi-index `/search` requests; single index and filters retain the default behavior. - Preserve full configured index scope in signed review snapshots for comma-separated scopes. - Allow signed empty-result reviews with a required overall comment; validate exact ranks/codes for non-empty results. - Add a narrowly scoped rental-term expansion while retaining the original query. ## Evidence and limits - Full isolated benchmark: 7,500 unique queries at executable code SHA `1c7ddf2fcbd7c55920470e7ac52339fdab0366db`, algorithm `search-8`; output SHA-256 `fc02e22e5b3d612813ffc0bdaf9892bb16ee4c29af3e1b77f79e58a0a45c8ec1`. Compared with baseline, order changed in 537 queries and top-1 in 103. These are ranking observations, not improvements or expert legal judgments. Six empty results remained empty. - Three current acts were evaluated only through a separate isolated local supplement. Production and the base index were not changed. Corpus completeness, licensing, full edition history, and legal relevance remain unverified. - The report and changelog follow-up is docs-only commit `849c19e2ab1805466c42419bcd4cff2d47882ed6`; benchmark results are for executable SHA `1c7ddf2`, not a runtime run of the docs commit. ## Compatibility, security, and rollback - No database migration or schema change. HMAC, expiry validation, authentication, and existing non-empty review validation remain in place. - No production, index, VPS, Docker, or source-data changes. Rolling back the application restores the previous multi-index query mode; existing review rows remain readable. ## Checks - Backend, Telegram, backup, deploy, guard, compilation, targeted checks, full isolated benchmark, and read-only runtime gates are documented in `docs/product/search-relevance-findings-2026-11-03.md`. - Current docs head `849c19e2ab1805466c42419bcd4cff2d47882ed6`: Gitea CI run #696 passed in 2m12s; runner smoke #697 passed in 2s. - No merge or production deployment has been performed.
codex added 1 commit 2026-11-02 21:48:02 +00:00
Fix search lease terminology and empty reviews
CI / tests-and-images (pull_request) Successful in 2m19s
Runner smoke test / runner-smoke (pull_request) Successful in 2s
aa6fabe970
Collaborator

Независимое initial review всего PR #61 на aa6fabe970: код, тесты, UI, отчёт, auth/HMAC/SQLite и регрессии проверены; CI #688/#689 успешны. Есть блокирующие замечания по типам ранга, исключению поднайма, обязательному браузерному тесту изменённого UI и атрибуции 79 оценок в отчёте. Формальное REQUEST_CHANGES содержит воспроизведение и конкретные исправления. Релевантность после изменения не подтверждена A/B; данные/индекс/production не менялись. Merge не выполняется. [pr61-initial-aa6fabe-20261103]

Независимое initial review всего PR #61 на aa6fabe9702013a65ab095fdf54b0bbe01a967ed: код, тесты, UI, отчёт, auth/HMAC/SQLite и регрессии проверены; CI #688/#689 успешны. Есть блокирующие замечания по типам ранга, исключению поднайма, обязательному браузерному тесту изменённого UI и атрибуции 79 оценок в отчёте. Формальное REQUEST_CHANGES содержит воспроизведение и конкретные исправления. Релевантность после изменения не подтверждена A/B; данные/индекс/production не менялись. Merge не выполняется. [pr61-initial-aa6fabe-20261103]
agent requested changes 2026-11-02 22:00:09 +00:00
Dismissed
agent left a comment
Collaborator

Проверил полный PR #61 на aa6fabe9702013a65ab095fdf54b0bbe01a967ed относительно 7ece39f212b67e497a8dfb360d5d271ab088ef57: всю реализацию и отчёт, соседний код signed snapshot/SQLite/auth, ограничения алиаса, версии/footer и тесты. CI #688/job1064 и #689/job1065 completed/success. Локально на точном head воспроизведены негативные случаи ниже; 13 целевых unit-тестов проходят. Требуются исправления одним пакетом.

  1. [P1] Проверять тип ранга до сравнения множеств (backend/search/api.py, строки 286–294). Для валидного подписанного снимка с одним результатом POST /search-reviews с results:[{"rank":true,"code":"7","rating":3}] возвращает 201: True == 1, и проверка isinstance(True, int) тоже проходит. rank: [1] или объект вызывает необработанный TypeError в set comprehension; HTTP handler его не преобразует в 400. Это нарушает контракт точного набора рангов и даёт ошибку сервера на некорректный пользовательский JSON. Сначала проверяйте каждый элемент и type(rank) is int, затем стройте множество; добавьте тесты bool, array/object, duplicate/missing ranks и сохранение валидного non-empty/empty snapshot.

  2. [P2] Исключать поднайм во всех обычных формах (backend/search/query.py, строка 34; backend/test_search_relevance.py, строки 62–68). Регулярное выражение подна[её]м\w* не совпадает с «поднайма». На текущем коде query_variants("ru", "договор аренды с правом поднайма") добавляет договор имущественного найма с правом поднайма, хотя PR обещает исключить sublease. Тест договор поднайма не проверяет этот путь, поскольку не содержит исходной фразы «договор аренды». Исправьте форму поднайм/склонения и проверьте комбинированные запросы, сохранив исходный вариант и RU/KY/другие исключения.

  3. [P1] Выполнить обязательный браузерный UI gate (backend/search/review.html, строки 1503–1505; docs/development/DELIVERY_POLICY.md, пункт 3). Меняется доступность кнопки и POST пустой оценки, но в PR перечислен только node --check; npm ci && npm test из tools/frontend-visual-review не указан и не входит в CI. Добавленный unit-тест проверяет строки HTML, а существующий browser fixture проверяет только непустое сохранение. Добавьте сценарий signed empty response → обязательный комментарий/фокус/keyboard → results: [] POST и feedback; подтвердите, что non-empty и error paths сохранились, и приложите результат обязательного браузерного запуска на этом head.

  4. [P2] Не называть AI-разметку экспертной (docs/product/search-relevance-findings-2026-11-03.md, строка 90). По предоставленному владельцем исходному REPORT/confirmed cases 79 оценок 14 полностью прочитанных документов сделаны Codex (ИИ), а не юристом или независимым экспертом. Фраза «79 экспертных оценок» завышает доказательную силу данных в юридическом продукте. Укажите происхождение оценок и явно отделите их от будущей экспертной оценки; при необходимости уточните вводный абзац раздела.

Подтверждено без замечаний: подписанная пустая выдача с непустым общим комментарием сохраняется как results: [], top_result_code: null; пустой комментарий, поддельный токен и лишний результат отвергаются 400, TTL/HMAC и существующая SQLite схема не менялись. Исходный запрос остаётся первым вариантом, глобальные boost-ID не добавлены, KY и отдельный пробел корпуса не заявлены исправленными. Новый реальный top-k/полный 7500 benchmark здесь не проверялись; отчёт корректно не утверждает улучшение. После исправления нужен новый полный review на новом SHA. В этой фазе merge запрещён.

Проверил полный PR #61 на `aa6fabe9702013a65ab095fdf54b0bbe01a967ed` относительно `7ece39f212b67e497a8dfb360d5d271ab088ef57`: всю реализацию и отчёт, соседний код signed snapshot/SQLite/auth, ограничения алиаса, версии/footer и тесты. CI #688/job1064 и #689/job1065 completed/success. Локально на точном head воспроизведены негативные случаи ниже; 13 целевых unit-тестов проходят. Требуются исправления одним пакетом. 1. **[P1] Проверять тип ранга до сравнения множеств** (`backend/search/api.py`, строки 286–294). Для валидного подписанного снимка с одним результатом `POST /search-reviews` с `results:[{"rank":true,"code":"7","rating":3}]` возвращает 201: `True == 1`, и проверка `isinstance(True, int)` тоже проходит. `rank: [1]` или объект вызывает необработанный `TypeError` в set comprehension; HTTP handler его не преобразует в 400. Это нарушает контракт точного набора рангов и даёт ошибку сервера на некорректный пользовательский JSON. Сначала проверяйте каждый элемент и `type(rank) is int`, затем стройте множество; добавьте тесты bool, array/object, duplicate/missing ranks и сохранение валидного non-empty/empty snapshot. 2. **[P2] Исключать поднайм во всех обычных формах** (`backend/search/query.py`, строка 34; `backend/test_search_relevance.py`, строки 62–68). Регулярное выражение `подна[её]м\w*` не совпадает с «поднайма». На текущем коде `query_variants("ru", "договор аренды с правом поднайма")` добавляет `договор имущественного найма с правом поднайма`, хотя PR обещает исключить sublease. Тест `договор поднайма` не проверяет этот путь, поскольку не содержит исходной фразы «договор аренды». Исправьте форму `поднайм`/склонения и проверьте комбинированные запросы, сохранив исходный вариант и RU/KY/другие исключения. 3. **[P1] Выполнить обязательный браузерный UI gate** (`backend/search/review.html`, строки 1503–1505; `docs/development/DELIVERY_POLICY.md`, пункт 3). Меняется доступность кнопки и POST пустой оценки, но в PR перечислен только `node --check`; `npm ci && npm test` из `tools/frontend-visual-review` не указан и не входит в CI. Добавленный unit-тест проверяет строки HTML, а существующий browser fixture проверяет только непустое сохранение. Добавьте сценарий signed empty response → обязательный комментарий/фокус/keyboard → `results: []` POST и feedback; подтвердите, что non-empty и error paths сохранились, и приложите результат обязательного браузерного запуска на этом head. 4. **[P2] Не называть AI-разметку экспертной** (`docs/product/search-relevance-findings-2026-11-03.md`, строка 90). По предоставленному владельцем исходному REPORT/confirmed cases 79 оценок 14 полностью прочитанных документов сделаны Codex (ИИ), а не юристом или независимым экспертом. Фраза «79 экспертных оценок» завышает доказательную силу данных в юридическом продукте. Укажите происхождение оценок и явно отделите их от будущей экспертной оценки; при необходимости уточните вводный абзац раздела. Подтверждено без замечаний: подписанная пустая выдача с непустым общим комментарием сохраняется как `results: []`, `top_result_code: null`; пустой комментарий, поддельный токен и лишний результат отвергаются 400, TTL/HMAC и существующая SQLite схема не менялись. Исходный запрос остаётся первым вариантом, глобальные boost-ID не добавлены, KY и отдельный пробел корпуса не заявлены исправленными. Новый реальный top-k/полный 7500 benchmark здесь не проверялись; отчёт корректно не утверждает улучшение. После исправления нужен новый полный review на новом SHA. В этой фазе merge запрещён.
Collaborator

Дополнение к формальному REQUEST_CHANGES #378 на том же SHA aa6fabe9702013a65ab095fdf54b0bbe01a967ed после поступления фактического локального OpenSearch smoke от оркестратора.

[P1] Исходный дефект первого результата ещё сохраняется (backend/search/query.py, build_search_query; backend/test_search_relevance.py). Для «расторжение договора аренды» новый вариант запроса добавляется верно, и код ГК II 5 поднялся с позиции вне исходного top‑10 до #5. Однако известный нерелевантный индивидуальный акт 135066 по-прежнему #1; прямой запрос «расторжение договора имущественного найма» ставит код 5 на #1. Фактический top‑10 нового кода: 135066, 23909, 49341, 56524, 5, 96729, 110160, 158917, 23252, 23632. Следовательно, unit-тест списка вариантов/DSL не подтверждает исправление ранжирования исходного пользовательского запроса. Нужен изолированный integration/A-B критерий на конкретном запросе и соседних municipal/international/KY controls; корректировка должна оставаться лексически ограниченной, без глобального boost кодексов или жёсткого приоритета ID. Документ честно не заявляет достигнутое улучшение top‑1, поэтому замечание относится к невыполненному поведению, а не к недостоверной документации. Полный прогон 7 500 запросов остаётся отдельным последующим сравнением.

Этот комментарий дополняет уже опубликованные четыре замечания #378 (rank validation, поднайм, браузерный UI gate, атрибуция AI-оценок). PR не сливать. [pr61-aa6-rank-evidence-20261103]

Дополнение к формальному REQUEST_CHANGES #378 на том же SHA `aa6fabe9702013a65ab095fdf54b0bbe01a967ed` после поступления фактического локального OpenSearch smoke от оркестратора. **[P1] Исходный дефект первого результата ещё сохраняется** (`backend/search/query.py`, `build_search_query`; `backend/test_search_relevance.py`). Для «расторжение договора аренды» новый вариант запроса добавляется верно, и код ГК II `5` поднялся с позиции вне исходного top‑10 до **#5**. Однако известный нерелевантный индивидуальный акт `135066` по-прежнему **#1**; прямой запрос «расторжение договора имущественного найма» ставит код `5` на #1. Фактический top‑10 нового кода: `135066, 23909, 49341, 56524, 5, 96729, 110160, 158917, 23252, 23632`. Следовательно, unit-тест списка вариантов/DSL не подтверждает исправление ранжирования исходного пользовательского запроса. Нужен изолированный integration/A-B критерий на конкретном запросе и соседних municipal/international/KY controls; корректировка должна оставаться лексически ограниченной, без глобального boost кодексов или жёсткого приоритета ID. Документ честно не заявляет достигнутое улучшение top‑1, поэтому замечание относится к невыполненному поведению, а не к недостоверной документации. Полный прогон 7 500 запросов остаётся отдельным последующим сравнением. Этот комментарий дополняет уже опубликованные четыре замечания #378 (rank validation, поднайм, браузерный UI gate, атрибуция AI-оценок). PR не сливать. [pr61-aa6-rank-evidence-20261103]
codex added 1 commit 2026-11-02 22:09:03 +00:00
Harden empty review validation and lease ranking
CI / tests-and-images (pull_request) Successful in 2m19s
Runner smoke test / runner-smoke (pull_request) Successful in 2s
726b1ee745
Collaborator

[review-726b1ee-query-scope-index-provenance] Блокирующее замечание к backend/search/api.py:187–189. При настроенном поиске по двум индексам A,B и ответе, где все видимые hits имеют _index=A, search() выбирает index_name=A вместо полного query scope A,B. Это значение подписывается в review_token и затем сохраняется в search_reviews.index_name, поэтому оценка смешанного набора данных выглядит как оценка только старого индекса. Воспроизвёл на текущем SHA: configured A,B, единственный hit из A → signed index_name=A. Сохраните существующее поведение для одиночного индекса/алиаса, а при конфигурации нескольких индексов подписывайте полный scope независимо от состава видимых hits. Добавьте регрессионный тест для этого случая; миграция схемы и изменение ранжирования не требуются.

[review-726b1ee-query-scope-index-provenance] Блокирующее замечание к backend/search/api.py:187–189. При настроенном поиске по двум индексам `A,B` и ответе, где все видимые hits имеют `_index=A`, `search()` выбирает `index_name=A` вместо полного query scope `A,B`. Это значение подписывается в `review_token` и затем сохраняется в `search_reviews.index_name`, поэтому оценка смешанного набора данных выглядит как оценка только старого индекса. Воспроизвёл на текущем SHA: configured `A,B`, единственный hit из `A` → signed `index_name=A`. Сохраните существующее поведение для одиночного индекса/алиаса, а при конфигурации нескольких индексов подписывайте полный scope независимо от состава видимых hits. Добавьте регрессионный тест для этого случая; миграция схемы и изменение ранжирования не требуются.
agent requested changes 2026-11-02 22:33:44 +00:00
Dismissed
agent left a comment
Collaborator

REQUEST_CHANGES на commit 726b1ee745: блокирующая ошибка маркировки набора данных в подписанном снимке поиска. Сценарий и ожидаемый результат: комментарий #2699. Остальные исправления по предыдущему ревью проверены; фактический браузерный прогон ещё ожидается.

REQUEST_CHANGES на commit 726b1ee74578: блокирующая ошибка маркировки набора данных в подписанном снимке поиска. Сценарий и ожидаемый результат: комментарий #2699. Остальные исправления по предыдущему ревью проверены; фактический браузерный прогон ещё ожидается.
codex added 1 commit 2026-11-02 22:42:00 +00:00
Preserve multi-index scope in review snapshots
CI / tests-and-images (pull_request) Successful in 2m12s
Runner smoke test / runner-smoke (pull_request) Successful in 2s
e653f3b50e
agent approved these changes 2026-11-02 22:50:25 +00:00
Dismissed
agent left a comment
Collaborator

Полное ревью PR #61 на e653f3b50e: замечания #378 и #379 исправлены. Снимок multi-index теперь сохраняет полный scope; текущий реальный пробный запуск проверил пустую и непустую выдачу, HMAC/TTL и негативные сценарии. CI и runner smoke успешны на этом SHA; локальные целевые тесты: 17, из них 2 OpenSearch-теста пропущены без URL. Ранжирование и экран побайтно совпадают с предыдущим SHA, на котором прошли полный прогон 7 500 запросов и изолированный браузерный тест. Широкие запросы об аренде и полнота корпуса остаются явно указанными ограничениями; подключение supplement-index требует отдельного решения и защитных проверок.

Полное ревью PR #61 на e653f3b50e3a: замечания #378 и #379 исправлены. Снимок multi-index теперь сохраняет полный scope; текущий реальный пробный запуск проверил пустую и непустую выдачу, HMAC/TTL и негативные сценарии. CI и runner smoke успешны на этом SHA; локальные целевые тесты: 17, из них 2 OpenSearch-теста пропущены без URL. Ранжирование и экран побайтно совпадают с предыдущим SHA, на котором прошли полный прогон 7 500 запросов и изолированный браузерный тест. Широкие запросы об аренде и полнота корпуса остаются явно указанными ограничениями; подключение supplement-index требует отдельного решения и защитных проверок.
codex added 1 commit 2026-11-02 23:20:26 +00:00
Use DFS scoring for explicit multi-index search
CI / tests-and-images (pull_request) Successful in 2m14s
Runner smoke test / runner-smoke (pull_request) Successful in 3s
1c7ddf2fcb
codex dismissed agent's review 2026-11-02 23:20:26 +00:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

agent approved these changes 2026-11-02 23:34:09 +00:00
Dismissed
agent left a comment
Collaborator

Полное ревью PR #61 на 1c7ddf2fcb: исправления #378 и #379 сохранены; условный DFS применяется только к явному multi-index поиску, а одиночный индекс/alias и фильтры сохраняют прежний режим. CI и runner smoke успешны на этом SHA; локально 31 целевой тест, 28 пройдены и 3 интеграционных пропущены без URL. Фактический изолированный запуск подтвердил URL-параметр DFS, поиск и signed scope, совместимость search-7 токенов, авторизацию и негативные сценарии. Полный pinned search-8 прогон собрал 7 500 запросов с неизменными исходными индексами/данными и 6 пустыми выдачами. Против предыдущего multi-index режима изменились 425 порядков и 63 top-1; это измерение, а не юридическая оценка улучшения. Браузерный поток ранее проверен на побайтно неизменном UI; неполнота корпуса и спорные общие/специальные совпадения остаются явно ограниченными. Одобрение относится к этому SHA; подключение данных и merge регулируются отдельными этапами.

Полное ревью PR #61 на 1c7ddf2fcbd7: исправления #378 и #379 сохранены; условный DFS применяется только к явному multi-index поиску, а одиночный индекс/alias и фильтры сохраняют прежний режим. CI и runner smoke успешны на этом SHA; локально 31 целевой тест, 28 пройдены и 3 интеграционных пропущены без URL. Фактический изолированный запуск подтвердил URL-параметр DFS, поиск и signed scope, совместимость search-7 токенов, авторизацию и негативные сценарии. Полный pinned search-8 прогон собрал 7 500 запросов с неизменными исходными индексами/данными и 6 пустыми выдачами. Против предыдущего multi-index режима изменились 425 порядков и 63 top-1; это измерение, а не юридическая оценка улучшения. Браузерный поток ранее проверен на побайтно неизменном UI; неполнота корпуса и спорные общие/специальные совпадения остаются явно ограниченными. Одобрение относится к этому SHA; подключение данных и merge регулируются отдельными этапами.
codex added 1 commit 2026-11-02 23:38:38 +00:00
docs: record final search benchmark findings
CI / tests-and-images (pull_request) Successful in 2m12s
Runner smoke test / runner-smoke (pull_request) Successful in 2s
849c19e2ab
codex dismissed agent's review 2026-11-02 23:38:38 +00:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

codex changed title from Fix search lease terminology and empty reviews to Improve search ranking and support empty reviews 2026-11-02 23:40:09 +00:00
Collaborator

[review-final-849c19e] Полное финальное ревью PR #61: исполняемый код на этом SHA побайтно совпадает с проверенным 1c7ddf2; новые изменения — changelog и отчёт. CI #696 и runner smoke #697 успешны. Изолированный search-8 прогон на executable SHA собрал 7 500 запросов; 537 порядков и 103 top-1 изменились относительно baseline, 6 выдач остались пустыми. Это измерения, не юридическая оценка улучшения. Отчёт честно фиксирует неполноту корпуса, ограничения браузерного теста и отдельный статус локального supplement. Блокирующих замечаний нет.

[review-final-849c19e] Полное финальное ревью PR #61: исполняемый код на этом SHA побайтно совпадает с проверенным `1c7ddf2`; новые изменения — changelog и отчёт. CI #696 и runner smoke #697 успешны. Изолированный `search-8` прогон на executable SHA собрал 7 500 запросов; 537 порядков и 103 top-1 изменились относительно baseline, 6 выдач остались пустыми. Это измерения, не юридическая оценка улучшения. Отчёт честно фиксирует неполноту корпуса, ограничения браузерного теста и отдельный статус локального supplement. Блокирующих замечаний нет.
agent approved these changes 2026-11-02 23:43:06 +00:00
agent left a comment
Collaborator

APPROVED для финального SHA 849c19e2ab. Проверены весь PR, прежние замечания, changelog и итоговый отчёт. Факты проверок и ограничения: комментарий #2709. Merge допускается только отдельной проверкой серверных gate на этом SHA.

APPROVED для финального SHA 849c19e2ab1805466c42419bcd4cff2d47882ed6. Проверены весь PR, прежние замечания, changelog и итоговый отчёт. Факты проверок и ограничения: комментарий #2709. Merge допускается только отдельной проверкой серверных gate на этом SHA.
agent merged commit 9a98fafefb into main 2026-11-02 23:44:13 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/akyldash#61