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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[![MCP](https://img.shields.io/badge/MCP-compatible-green.svg)](https://modelcontextprotocol.io/)
[![Zed](https://img.shields.io/badge/Zed-extension-orange.svg)](https://zed.dev/)
[![CI](https://github.com/ManSio/mscodebase-intelligence/actions/workflows/ci.yml/badge.svg)](https://github.com/ManSio/mscodebase-intelligence/actions/workflows/ci.yml)
[![Tests](https://img.shields.io/badge/tests-1965%20passed-brightgreen)](tests/)
[![Tests](https://img.shields.io/badge/tests-2001%20passed-brightgreen)](tests/)

[Features](#-features) • [Quick Start](#-quick-start) • [Tools](#mcp-tools-65-total) • [Documentation](#-documentation-map) • [Installation](docs/en/INSTALL.md) • [Architecture](docs/en/ARCHITECTURE.md) • [Contributing](CONTRIBUTING.md) • [Security](SECURITY.md)

Expand Down Expand Up @@ -118,7 +118,7 @@ Designed and tested on **Windows**. macOS and Linux should work but have not bee
| 💾 **LanceDB v2** | Vector DB with per-project isolation (incremental BM25 reindex) |
| 🛡 **Rate Limiting** | DebounceBatch + CircuitBreaker — protection against VFS loops |
| 🏥 **Self-Diagnosis** | `get_health_report` + `index_health` — full check and recovery |
| 🧪 **Clean Architecture** | DI Container (14 services), 65 tools (32 core + 16 intel + 13 inline + 4 dev), ~1889 tests |
| 🧪 **Clean Architecture** | DI Container (14 services), 65 tools (32 core + 16 intel + 13 inline + 4 dev), 2007 tests |
| 🪟 **Multi-Window** | `ProjectIndexerRegistry` — isolated Indexer per project, LRU 5, ResourceMonitor throttle |
| ✏️ **Write Tools** | `codebase(action=...)` — unified hub: rename, move, delete, replace, insert, ack |
| ⚡ **Meta-Patching** | LanceDB `move_chunks_metadata` — file_path rename without re-embedding (50ms vs 5s) |
Expand Down
17 changes: 16 additions & 1 deletion WISDOM.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@
(get_variable_flow/get_related_files/run_health_check/predict_eta — 0 в src/),
get_index_status/git(action)/watcher_status — action-маршруты codebase hub,
не отдельные MCP-тулы (единственная регистрация — register_all_tools).
Факты: intel_*=14, core=28, inline=12, dev=4, tests=1180. Правило:
Факты (слепок на дату записи, НЕ текущие значения): intel_*=14, core=28, inline=12,
dev=4, tests=1180. Правило:
каждое имя тула в AGENTS.md обязано быть в списке tool_name (grep-гейт).
- ГЕЙТ РЕАЛИЗОВАН (2026-08-12): scripts/check_tool_names.py в pre-commit —
мёртвые имена → error; intel_* сверка с реестром; negative control 6 тестов.
Expand Down Expand Up @@ -239,3 +240,17 @@
revision gate VALID. Новый core (quiet_break_gate/redact/restraint) прошёл clean-state.
- Если ветка не запушена, default clone с GitHub тестирует ЧУЖОЕ (origin) состояние — для честного
clean-state клонировать ЛОКАЛЬНЫЙ репо и гонять --no-clone.

## Живая перепись публикуемых чисел (2026-10-03)
- Правило: **число внутри датированного слепка помечается как слепок**, а текущее значение живёт
отдельно и проверяется командой, а не памятью. Основание: benchmark decay — «число остаётся
прежним, то, что оно измеряет, размывается».
- Текущие значения (пере-меряются, не выдумываются):
`intel_*=20`, `tests=2007 collected / 2001 passed`, `6 skipped`.
- Команда пересчёта: `python tools/verification/verify_public_claims.py`
(каждое утверждение имеет свою команду; расхождение → rc=3).
- Guard: `python tools/verification/verify_public_claims.py --selftest` — 4 синтетических кейса,
2 обязаны отклоняться. Урок: проверка `live <= stated` односторонняя — она пропустила бы бейдж,
завышающий число; симметричное сравнение ловит обе стороны.
- Старые `intel_*=14 / tests=1180` оставлены как исторические слепки: правка опубликованного
числа — новая запись со ссылкой на старую, а не молчаливая замена.
1 change: 1 addition & 0 deletions tools/knowledge/PATTERNS.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
| **P-14** | `text=True` без `encoding=` декодирует по локали: на Windows-консоли cp1251, любой не-ASCII байт роняет вызов (14/14 мест) | `locale.getpreferredencoding(False)` вместо явного UTF-8 | `encoding="utf-8", errors="replace"` во всех subprocess-вызовах | local: (P-0 проекта) | аудит Tirthahq 2026-09-30, `scripts/audit_protocol_guards.py` |
| **P-15** | Публикуемое число не воспроизводится сегодняшней командой: у нас 2 из 14; у коллеги 84 → 107 на неизменённом коммите | Число не привязано к существующей команде | `measured on <sha>, superseded by X`; различать «число ошибочно» и «число мертво (путь удалён по дизайну)» | §19.11 | `AGENT_DIARY.md:79-96` |
| **P-16** | Аудит чужого/своего кода нашим же реестром даёт 5 совпадений из 5 — и обратный вывод в нашу пользу: **наш собственный код изначально был в том же состоянии**, мы вышли из него не знанием, а guard'ами | Реестр описывает прошлое, а не класс ошибок | Периодически применять реестр к постороннему проекту | §19.8 | `AGENT_DIARY.md` (guard-comparison 2026-09-30) |
| **P-17** | Benchmark decay: опуликованное число разъезжается с реальностью молча (бейдж 1965 vs 2007, census intel 14 vs 20, tests 1180 vs 2007 — расхождения 42/6/827). Класс назван в литературе (GTM-Bench «Keeping a Benchmark Honest»), а не «наша ошибка в редактуре» | Число опубликовано без команды, которая его перевыводит; ручная правка без guard | tools/verification/verify_public_claims.py — каждое утверждение хранит свою команду; расхождение → rc=3; сравнение симметрично (ловит и завышение) | §19.11 | tools/knowledge/RESEARCH-benchmark-decay.md |

---

Expand Down
89 changes: 89 additions & 0 deletions tools/knowledge/RESEARCH-benchmark-decay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# RESEARCH: benchmark decay и documentation drift (2026-10-03)

Задача: почему опубликованные числа в README/WISDOM разошлись с реальностью, и есть ли
у этого класса имя и готовые защиты. Не гадать — найти первичные источники.

## T1. GTM-Bench, "Keeping a Benchmark Honest" (2026-09-06) — прямое попадание

Класс назван: **benchmark decay**.

> "Nothing leaked at construction time, but the benchmark is public and static, so over
> months the field optimizes toward it. The number stays the same; what it measures erodes."

Каноническая защита — структурная, а не разовая:

> "Versioned releases — every reported score names the version it was run against;
> **a number without a version is uninterpretable.**"

**Наше применение.** Бейдж `tests-1965 passed` — именно такое число: публичное, статичное,
без версии. Через 42 теста он перестал описывать то, что измерял. Это не наша ошибка
в редактуре — это оформленный класс с именем.

Вывод, который меняет дизайн: чинить бейдж разово (`1965 → 2001`) недостаточно.
Достаточно только **закрепить число за командой, которая его перевыводит** — тогда оно
не сможет разъехаться снова незамеченно.

## T2. READU (arXiv 2607.15780) — README-баги как класс

Таксономия true-positives у них совпадает с нашими кандидатами:
implementation–documentation drift, incorrect external references, invalid usage
instructions, cross-document/translation/naming drift.

Конструкция проверки цитируется почти дословно:

> "a high-recall commit filter, runs internal and external consistency checkers in
> parallel, **uses an alert judge to remove false positives**"

**Наше применение.** Триаж — обязательная часть конструкции, а не опция. Это ровно то,
что пришлось делать дважды вручную в этой задаче, причём оба раза автоматическая
классификация ошиблась в противоположные стороны (см. T4). У них судья встроен в
конвейер по построению.

## T3. driftmd — «badge versions» как отдельная проверка

Их чек-лист содержит пункт целиком:

> "Badge versions" — бейдж объявляет одну версию, а манифест проекта — другую

(дословный пример из их чек-листа содержит чужие номера версий и намеренно не
воспроизводится: `stale_detector` в pre-commit читает такой литерал как версию
нашего проекта и справедливо ругается. Цитата чужого источника не должна
превращаться в утверждение о нашем коде.)

Наш дефект — ровно этот пункт, отдельной строкой. Значит класс известен и инструментально
покрыт; отсутствие у нас проверки не оправдание, а пробел.

## T4. Что НЕ сработало (обязательная часть, §19.1)

Гипотезы, заранее внесённые как **ожидаемые к провалу**:

| Гипотеза | Фальсификатор | Итог |
|---|---|---|
| Достаточно исправить числа вручную | правка без guard'а → повторный дрейф через N коммитов | ✅ подтверждена как недостаточная (защита = команда + selftest) |
| Достаточно сравнения «live ≥ stated» | завышенный бейдж должен быть пойман | ❌ **ОПРОВЕРГНУТА**: односторонняя проверка пропустила `stated=1999999` |
| README/WISDOM — единственные носители | grep по всему трекнутому дереву | ❌ ОПРОВЕРГНУТА: 7 файлов содержат `Users\misha` вне охвата гейта |
| Числа в датированных слепках — устаревшие баги | слепок от 2026-08-12 был истинным на ту дату | ❌ ОПРОВЕРГНУТА: `intel_*=14` тогда было **правильно**; «баг» — чтение слепка как текущей истины |

Четыре из четырёх заранее-слабых гипотез рухнули. Это и было целью: без них отчёт
выглядел бы как «4/4 успеха» и ничего не значил бы.

## T5. Граница нашего собственного guard'а (честная формулировка)

`tests/test_no_personal_paths.py` зелёный, а `git grep` находит 7 трекнутых файлов с
`Users\misha` (`.local/*.py`, `docs/archive/*.md`, `scripts/reconstruct_judge_cot.py`).
Тест **не слепой пятки** — он объявляет свою границу в docstring: человекочитаемые докси +
`docs/**` минус архивы + плагин; `scripts/**` и `.local/**` вынесены «в отдельную
ревью-проходку».

По §19.7 честная формулировка вторая: измеряем не «у нас дыра в безопасности», а то,
что **«ты вне объявленной поддержки» никогда не сообщается читателю**. Архивы —
историческая запись, их переписывание нарушило бы §8/§19.11; `scripts/*.py` с
захардкоженным путём — реальный порт дефект, но это отдельная задача, не эта.

## Вывод (применён)

1. Число публикуется только вместе с командой, которая его перевыводит.
2. Проверка симметрична: завышение ловится так же, как недооценка.
3. Датированный слепок помечается как слепок; текущее значение живёт отдельно.
4. Selftest обязан содержать кейсы, которые обязаны быть **отклонены** — иначе guard
не умеет падать и является декорацией.
10 changes: 5 additions & 5 deletions tools/verification/denominator_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
"repo/KNOWN_ISSUES.md": {
"class": "INTERNAL",
"reason": "internal board; public via known-issues.json",
"n_sig1": 14,
"n_sig2": 692,
"n_sig1": 16,
"n_sig2": 741,
"n_reviewed": 0,
"profiles": [
"full",
Expand All @@ -68,7 +68,7 @@
"class": "PUBLIC",
"reason": "public readme",
"n_sig1": 24,
"n_sig2": 109,
"n_sig2": 108,
"n_reviewed": 0,
"profiles": [
"full",
Expand All @@ -78,8 +78,8 @@
"repo/WISDOM.md": {
"class": "INTERNAL",
"reason": "internal distilate",
"n_sig1": 7,
"n_sig2": 204,
"n_sig1": 8,
"n_sig2": 213,
"n_reviewed": 0,
"profiles": [
"full",
Expand Down
19 changes: 14 additions & 5 deletions tools/verification/run_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
("gates: scope + decisive region declared (RT8)", [PY, str(G / "heldout_rt8_scope.py")], 0),
("G2: publishable-number controls", [PY, str(G / "heldout_g2_publishable.py")], 0),
("G5 denominator: no unregistered numbers", [PY, str(G / "g5_denominator.py")], 0),
# Benchmark decay guard: the badge and the census in README/WISDOM were 42, 118,
# 6 and 827 tests out of date respectively. Both were published numbers a reader
# could cite. The selftest proves the comparison can reject in BOTH directions —
# a one-sided `live <= stated` check passed an inflated badge and was caught here.
("claims: check can reject both directions", [PY, str(G / "verify_public_claims.py"), "--selftest"], 0),
("claims: published numbers reproduce today", [PY, str(G / "verify_public_claims.py")], 0),
("suite: portable, no author-absolute paths", [PY, str(G / "heldout_relocation.py")], 0),
# The command files (.opencode/command/) cite these exact invocations. If the CLI
# changes shape, the commands become prose that cannot be run, which is worse than
Expand All @@ -60,10 +66,13 @@

# Steps that SURFACE findings without deciding pass/fail. Marking a noisy guard as a gate
# is worse than not gating: a red CI on untriaged noise trains everyone to ignore red.
# Per В§19.5 the guard may not be published as a verdict until its false-positive share is
# measured — so this is reported as an open measurement, not silently passed and not failed.
# Per §19.5 the guard may not be published as a verdict until its false-positive share is
# measured — so this is reported as an open measurement, not silently passed and not failed.
# FP share MEASURED 2026-10-03 by scripts/triage_protocol_findings.py: 8 reported,
# 5 false positives = 62.5%, 3 actionable. The number is surfaced WITH its false-positive
# share; quoting "8 findings" alone would overstate the defects by 2.7x.
SURFACE = [
("protocol guards: findings (un-triaged, FP ratio UNMEASURED)",
("protocol guards: findings (FP share measured: 62.5% of 8 reported)",
[PY, str(REPO / "scripts" / "audit_protocol_guards.py")]),
]

Expand Down Expand Up @@ -98,8 +107,8 @@ def main() -> int:
m = [x for x in out.splitlines() if "finding" in x.lower() and ":" in x]
n = m[-1].split(":", 1)[1].strip() if m else "?"
print(f"[OPEN] {name:52} {n}")
print(" neither a pass nor a fail: this guard's false-positive share is NOT measured.")
print(" Until it is, the number must not be quoted as 'N problems' (protocol 19.5).")
print(" FP share measured 62.5% (5 of 8 were noise) -> 3 actionable.")
print(" Quoting the raw finding count as 'N problems' overstates defects by 2.7x (§19.5).")

print("=" * 78)
if failed:
Expand Down
Loading
Loading