Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions AGENT_DIARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,48 @@
docs-only коммиты, им отвечать нечего); на решаемых 40 пустых 13, и это уже другой
вывод. Guard: `duplicate_positions.py` теперь применяет фильтр бенчмарка и падает
с кодом 2 при несовпадении популяции.
- **E73 — ночь 2026-11-11 (изменено / измерено / отклонено):**
- *Изменено:* `_abstains` отказывает только когда не встречается ни одно имя;
регрессионный тест «все идентификаторы по нулям → rows=0, abstain, next:»;
постскриптум в замороженной спеке про дефект планки P4.
- *Измерено:* sqlalchemy 11→17/40 hit@5 (P1 ≥15 — да), B1 dev 19/71 без
изменений (P2), 44/44 негатива молчат (P3), 6/13 восстановлено (P4 — FAIL,
планка была выведена из bypass-прогона), requests 10→12/25 при планке ≥10 (P5).
- *Отклонено:* править планку P4; второй независимый ревью; менять семантику
evidence-gate (это E74); дедуп по файлу как дефолт (E72 отрицательный).
- **Две ночные «дыры» закрыты (2026-11-11):**
- *smoke_e2e шаг 4* падал `no vector column` на дефолтном текстовом индексе
(`MSCODEBASE_DENSE_OFF=true`). Теперь шаг пробует вектор и честно падает в
SQLite FTS5 (`chunks_fts`), называя режим: `✅ PASSED (проверок: 4)`,
шаг 4 `режим=text … results=3`.
- *4 slow-теста* `test_lsp_vfs_indexing.py` конструировали `Indexer` без
`WorkspaceSource`; маркер `slow` исключён `addopts`, поэтому дрейф не видел
ни pre-commit, ни CI. Хелпер передаёт `LocalFsSource(project_path)`:
`pytest tests/ -m "not integration and not benchmark"` → `2560 passed, 10 skipped`.
- *Урок:* гейт, который не запускается (маркер исключён), — не гейт; «дыра»
нашлась только потому, что ночной прогон потребовал именно эту команду.
- **E73 — ревью и правило конверсии (2026-11-11):** вердикт независимого ревью —
«PASS с замечаниями», блокеров нет, два major. Применено правило конверсии:
**мерж приостановлен**, решение за владельцем утром.
- *major 1 (расхождение чтения):* предупреждение «the results below are
neighbours, not matches» остаётся привязано к первому имени и теперь врёт на
восстановленных ответах (строка — реальный хит по второму имени). Но тест
`test_no_exact_hits_says_the_results_are_neighbours` фиксирует этот контракт,
поэтому правка меняет контракт теста — это решение владельца, не моё.
- *major 2 (остаточная ложь в механизме):* `per` считается по первым двум
идентификаторам (`idents = identifiers[:2]`), а извлекается до четырёх;
отказ срабатывает, даже если третье имя встречается. Утверждение «ни одно
имя не встречается» сильнее кода; исправление меняет охват grep-канала и
требует перезамера P1/P5 — вне ночного объёма.
- *nit 4–6 исправлены в том же проходе:* `None`/отрицательные счётчики теперь
fail-open («неизвестно» ≠ «отсутствует»), мёртвая ветка убрана.
- P5 снят и записан до мержа: requests 10→12/25 при планке ≥10.
- **E73 (ложный отказ):** `_abstains` решал «субъекта нет» по ПЕРВОМУ
идентификатору; на прозе коммитов это `_orm.registry=0` при `Declarative=785`,
и 13 из 40 коммитов sqlalchemy отвечали пустотой. Отказ теперь только когда не
встречается ни одно имя: hit@5 11→17/40, B1 dev 19/71 без изменений, 44/44
негатива молчат. Планка P4 (8/13) была выведена из bypass-пути и не достижима
при сохранённой политике — записано как ошибка спеки, не подгонялось.
- **E71 (Change-Id):** хеш из Gerrit занимал первый слот идентификаторов, гейт считал
`0` вхождений и отказывал на каждом коммите sqlalchemy (0/40). Фильтр хешей и
трейлеров поднял tool до 11/40, B1 dev не изменился (19/38/22/2).
Expand Down
54 changes: 54 additions & 0 deletions EXPERIMENTS_LOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,58 @@
# EXPERIMENTS_LOG.md — Audit Verification (2026-07-22)
## [2026-11-11] — E73/P5: removing the false refusal costs the requests panel nothing

Rerun of B2 (`psf/requests`, 25 solvable commits, corpus `e331a288`, 786 chunks)
with the E73 fix. Pre-registered bar: **tool hit@5 >= 10 / 25** — the value
recorded for this panel in PR #110. No re-barring.

```
arm hit@1 hit@5 PR #110 -> now
tool 9 12 10 -> 12
neighbours 9 13 13
search 5 15 15
grep 6 19 19
invalid runs: 0
```

Bar passed; no arm lost a task. On this smaller repo the refusal was hiding two
answers as well, so the fix is not a large-repo-only effect.

Command:
`python experiments/bench_2026_11/external.py --repo <bench>/requests --corpus <bench>/req-B --base e331a288 --limit 40`
(`<bench>` = the directory with the external clones, see
`experiments/bench_2026_11/REPORT.md` → Reproduce).

## [2026-11-11] — E73: the first-token abstain refused answers the tool had found

**Found by** the E72 follow-up. On the 40 solvable sqlalchemy commits, 13 answered
nothing (`rows=0`, `abstain 0.00`) while the rows existed: `_abstains` decided
"the subject does not occur" from the FIRST extracted identifier
(`investigate_tool.py:138`), and on commit prose that token is an annotation or a
type name: `_orm.registry=0` next to `Declarative=785`, `Databricks=0` next to
`TypeError=290`.

**Fix:** refuse only when NO identifier occurs. The policy (option C, E69) is
untouched - 2 of the 13 still refuse because every token is absent.

```
sqlalchemy, 40 commits hit@5 before 11 -> after 17 (bar >=15: PASS)
B1 dev, 71 commits 19/71 both ways (bar 19: PASS)
44 negative tasks 44/44 silent, no leak (PASS)
13 formerly-empty 6/13 recovered (bar 8: FAIL)
```

P4 was miscalibrated in my own spec: the bar of 8 came from an
`include_neighbours=true` run, which bypasses the refusal, while the change keeps
it. Two of the thirteen are the all-zero case and must stay refused, so the
reachable maximum is 11/13. The gate is recorded as failed and NOT re-edited; the
frozen rule says "P4 < 8 -> revert", its premise ("the first-token rule is not
the cause") is contradicted by P1 (+6, no leak), so the ship decision is with the
owner.

**Still unexplained:** with the refusal removed, the same commit shows the gold
in the top-5 under the bypass path but not in the normal answer for 2 cases
beyond the all-zero pair - the evidence gate drops those rows. Not investigated.

## [2026-11-11] — E72: file-level dedup changes the shape, not the score

**Why:** on external repos the tool answers with chunks while grep ranks whole
Expand Down
109 changes: 52 additions & 57 deletions KNOWN_ISSUES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,58 @@
> Синхронизируется из `AGENT_DIARY.md` при каждом [🏁 ИТОГ].
> Формат: дата | что было | статус | fix

---
## 2026-11-11 — `smoke_e2e` шаг 4 требует dense-индекс, дефолт репозитория — текстовый — 🟢

- **Измерено:** `python scripts/smoke_e2e.py --project .` → шаг 4
`❌ search error: There is no vector column in the data. Please specify the
vector column name for vector search`; `.mscodebase/` содержит только
`chunks.db`, потому что индекс собран `scripts/reindex_text_only.py` при
`MSCODEBASE_DENSE_OFF=true` (дефолт проекта).
- **Не регресс:** шаг не зависит от `_abstains`; `--services-only` проходит
(`embed dim=768`, `rerank top=1`).
- **Fix:** шаг пробует вектор и при его отсутствии честно падает в текстовый
индекс SQLite (`chunks_fts`), называя режим в отчёте. Проверка:
`python scripts/smoke_e2e.py --project .` → `✅ SMOKE E2E: PASSED (проверок: 4)`,
шаг 4 `режим=text (vector: …); term=…, results=3`.

---
## 2026-11-11 — 4 slow-теста LSP/VFS не проходили на `main` — 🟢

- **Измерено (не наш регресс):** на `origin/main` (`74191a5`) падали
`tests/test_lsp_vfs_indexing.py::TestLSPVFSIndexing::test_lsp_vfs_content_indexed_without_disk`,
`…::test_lsp_vfs_content_beats_disk`, `…::test_indexed_at_timestamp`,
`…::test_hash_based_on_content_not_disk` — все с
`ValueError: Indexer requires an explicit WorkspaceSource`.
- **Причина:** тесты конструируют `Indexer` без `source=`, а API требует
explicit `WorkspaceSource`; маркер `slow` исключён `addopts`, поэтому дрейф не
видел ни pre-commit, ни CI.
- **Fix:** тестовый хелпер передаёт `LocalFsSource(project_path)`; проверка
`python -m pytest tests/test_lsp_vfs_indexing.py -o addopts="" -q` → `4 passed`.
Полный прогон с slow: `pytest tests/ -m "not integration and not benchmark"` →
`2560 passed, 10 skipped`.

---
## 2026-11-11 — E73: что осталось открытым после снятия ложного отказа — 🟡

- **Измерено на `sqlalchemy` (40 решаемых коммитов, база `8b62343`):** до фикса
пустых ответов 13; после — 6 восстановлены, 2 отказа законны, 4 промаха
ранжирования, 0 потерь от гейта доказательств.
- **Законные отказы (2):** `749086adb0cc`, `049ed1db162a` — у обоих все
идентификаторы по нулям (`mapped_column.default_factory=0`,
`mapped_column.default=0`); это политика C (E69), не дефект.
- **Промахи ранжирования (4):** `65ea6bee8214`, `98ad157d6334`, `975ffa7d77ee`,
`956a0235027e` — в ответе 8 строк, gold вне top-5.
- **Заявленные «2 дропа evidence-gate» не воспроизвелись:** разница
bypass-прогона (8/13) против фикса (6/13) — это ровно те два случая с нулями.
Чтобы поймать отбрасывание строки самим гейтом, нужен замер с
инструментированием `kept` — он не делался.
- **Перевывод:** `python experiments/false_abstain_2026_11/verify.py --corpus <bench>/sa-B
--repo <bench>/sqlalchemy --base 8b62343 --panel experiments/scale_2026_11/tasks.jsonl`
печатает per-task `hit@5` и список пустых; все id выше — его вывод
(`<bench>` — каталог с клонами, команды клонирования в
`experiments/bench_2026_11/REPORT.md`).

---
## 2026-11-09 — RU→EN: перевод сильнее dense; ревью поймало 2 ложных доказательства — 🟢

Expand Down Expand Up @@ -134,27 +186,6 @@ manifest-parity), `TrustBoundary`, modification-guard (HMAC `ack_impact` + `bind

---

## 2026-10-25 — README rewritten; RU/ZH synchronized — 🟢
- Root `README.md`, `docs/ru/README.md`, `docs/zh/README.md` now describe the
Phase 3 text-first runtime (SQLite/FTS5 + PropertyGraph, optional providers),
measured quality with methodology, limitations and bug-report protocol.
- Old claims removed: LanceDB/vector as default, 65 visible tools, inconsistent
test counts, 95% quality implication.
- Historical architecture/search docs carry a Phase 3 status banner; they are
not silently presented as current.

---

## 2026-10-25 — E57: auto docs routing by BM25 margin (no LLM) — 🟢
- `docs_max - code_max > 4.0` -> docs channel, else code.
- same-basename **0.688 → 0.792**, docs 5/8, **0 code false positives**;
code hit@1 0.825 unchanged; exact 0.708; p50 ~100 ms extra.
- **Реализовано:** `MSCODEBASE_DOCS_MARGIN` (4.0), `Searcher.prefers_docs()`,
auto-ветка в `SearchCodeTool` при пустом `intent`; tests 27 pass.
- Gold canonicalization (`docs/ru/X` for `docs/en/X`) всё ещё искажает exact.

---

## 2026-10-25 — E55/E56: chain modes; docs gold-language bottleneck — 🟡
- **E55:** hybrid/quality/deep 0.688/0.771 (p50 45–48 ms); fast 0.542/0.729
(p50 19 ms); `nodemote/intent/ru/p3` — 0 эффекта на hit@1.
Expand Down Expand Up @@ -234,15 +265,6 @@ manifest-parity), `TrustBoundary`, modification-guard (HMAC `ack_impact` + `bind

---

## 2026-10-25 — E45: structured agent plan — +1 h1, p50 72 ms — 🟢 worth API
- **План:** primary + must_include + symbols, один запрос, без multi-query RRF.
- **Результат:** baseline 0.688/0.771/79ms; plan_must **0.708**/0.771/71ms; plan_full 0.708/0.771/72ms.
- **Вердикт:** один primary + must_include — маленький реальный выигрыш; symbols не дают.
Внедрить как опциональные поля `search_code` + tool `plan_search`. 95% не закрывает.
- **Артефакты:** `experiments/e45_agent_plan/`.

---

## 2026-10-25 — E44: agent rewrites — keywords +1 h1; fusion/identifiers хуже — 🟡
- **Плечи:** baseline / keywords / identifiers / agent_all на 48 запросах E30.
- **Результат:** baseline 0.688/0.771, 84 ms; keywords **0.708**/0.771, 78 ms;
Expand Down Expand Up @@ -271,30 +293,3 @@ manifest-parity), `TrustBoundary`, modification-guard (HMAC `ack_impact` + `bind

---

## 2026-10-25 — E39: Qwen3-Reranker-0.6B — 29–55 s, хуже — 🔴 rejected
- **Пилот:** 16 запросов E30; demote vs Qwen3 top10/top20 на corrected index.
- **Результат:** demote 0.625/0.688, 116 ms; Qwen3 top10 0.500/0.562, 28.9 s;
top20 0.438/0.562, 54.8 s. H1–H6 FAIL.
- **Вердикт:** не usable на CPU; качество ниже deterministic. Reranking не рычаг.
Deterministic 0.688/0.771/84 ms — потолок на этой панели.
- **Артефакты:** `experiments/e39_qwen3_rerank/`.

---

## 2026-10-25 — E38: BGE-reranker-base — хуже deterministic — 🔴 rejected
- **Плечи:** demote / bge_base_top10 / top20 на 48 запросах E30 (corrected index).
- **Результат:** demote 0.688/0.771, 84 ms; BGE-base top10 0.625/0.708, 3139 ms;
top20 0.583/0.688, 6028 ms. H7 PASS (лучше MiniLM); остальные FAIL.
- **Вердикт:** generic cross-encoder out-of-domain для кода. Детерминированный pipeline 0.688/0.771/84 ms.
Reranking не рычаг; только Qwen3-Reranker-0.6B как пилот.
- **Артефакты:** `experiments/e38_code_aware_rerank/`.

---

## 2026-10-25 — E37: chunking 32/64/128 — качество не меняется; P3 off — 🟢
- **Результат:** current/split32/split64/split128 — все h1 0.688, h5 0.771, MRR 0.713.
- Нарезка не узкое место; top-5 определяется file-level ranking. P3 off: p50 87 ms,
качество не падает. `MSCODEBASE_P3_ANCHOR=false` по умолчанию.
- **Артефакты:** `experiments/e37_chunking/`.

---
4 changes: 2 additions & 2 deletions WISDOM.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ erify_clean_state.sh --no-clone на локальном clone закоммиче
отдельно и проверяется командой, а не памятью. Основание: benchmark decay — «число остаётся
прежним, то, что оно измеряет, размывается».
- Текущие значения (пере-меряются, не выдумываются):
`intel_*=20`, `tests=2446 collected / 2439 passed, 0 failed, 7 skipped`
(полный прогон 2026-11-09; 97 deselected маркерами `not slow and not benchmark`).
`intel_*=20`, `tests=2476 collected / 2469 passed, 0 failed, 7 skipped`
(полный прогон 2026-11-11; 97 deselected маркерами `not slow and not benchmark`).
- Команда пересчёта: `python tools/verification/verify_public_claims.py`
(каждое утверждение имеет свою команду; расхождение → rc=3).
- Гейт: `tools/verification/verify_public_claims.py --selftest` — 4 синтетических кейса,
Expand Down
26 changes: 24 additions & 2 deletions docs/FACTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> One page, every public number, and the command that regenerates it.
> If a number is not on this page, it is not a fact yet.
> Update date: **2026-11-08**.
> Update date: **2026-11-11**.

## 1. Identity

Expand Down Expand Up @@ -85,7 +85,29 @@ No 95% claim: static retrieval on this panel did not reach it.
| Cost of `scope=code` | ≈1.2 s → ≈2.2 s on 509 files | same call |
| `investigate` latency | ~1–2 s per typical question (7 channels, 2 passes) | any `investigate` call |

## 7. What is not a number
## 7. External-corpus benchmark (E70–E73, 2026-11-11)

Two external repositories, questions and gold written by other people: query =
commit message, gold = files the commit changed, corpus pinned at a base commit
so the fix is not indexed. `hit@5` = the gold file is in the first five rows.

| Fact | Value | How to check |
|---|---|---|
| `psf/requests`, 25 commits, corpus `e331a288` | `tool` **12/25**, `search` 15/25, `grep` 19/25 | `python experiments/bench_2026_11/external.py --repo <bench>/requests --corpus <bench>/req-B --base e331a288 --limit 40` |
| `sqlalchemy`, 40 commits, corpus `8b62343` | `tool` **17/40**, `search` 18/40, `grep` 20/40 | same command with `--repo <bench>/sqlalchemy --corpus <bench>/sa-B --base 8b62343` |
| B1 dev (this repo), 71 commits | `tool` **19/71** | `python experiments/bench_2026_11/run.py --split dev` |
| Negative panel, 44 fabricated names | **0/44 answers** | `python experiments/false_abstain_2026_11/verify.py --corpus <bench>/sa-B --repo <bench>/sqlalchemy --base 8b62343 --panel experiments/scale_2026_11/tasks.jsonl` |
| `grep` beats the tool on commit localization | yes, both external repos above | the same two commands |

`<bench>` is the directory holding the cloned repositories and their
`git worktree` copies; the clone and worktree commands are in
`experiments/bench_2026_11/REPORT.md` ("Reproduce").

The tool is **not** better than grep at localizing a commit message on these
corpora; the claim "better than grep" was about symbol lookup on the generated
panel, and it does not generalize.

## 8. What is not a number

- "Better than RAG" is not claimed anywhere in this repository.
- The docs-vs-code gold mismatch (`docs/ru/X` for `docs/en/X`) is a labeling
Expand Down
Loading
Loading