Skip to content

Feat/lsp thin client - #13

Merged
ManSio merged 14 commits into
mainfrom
feat/lsp-thin-client
Aug 28, 2026
Merged

ManSio merged 14 commits into
mainfrom
feat/lsp-thin-client

Conversation

@ManSio

@ManSio ManSio commented Aug 28, 2026

Copy link
Copy Markdown
Owner

No description provided.

MSCodeBase Agent added 14 commits August 25, 2026 21:22
…st-fail + to_thread

Commit b03073c fixed only the search query path; status/context tools still
froze the loop: IndexProjectRunner.begin_write() holds the shared RLock for
the entire reindex (~7.5 min embedding), and IndexStatusReporter.get_status()
(sync, on the event-loop thread via intel_get_runtime_status,
require_ready_project, ProjectContext) waited on the same lock → every MCP
call incl. debug_runtime_passport timed out client-side.

- IndexStatusReporter.get_status(): reindex fast-fail — instant cached status
  + status='reindexing' when db_manager.is_reindexing() is True (strict
  is True: MagicMock-truthy trap 2026-08-13).
- intel_get_runtime_status / MCPTool.require_ready_project /
  ProjectContext._capture_registry: get_status via asyncio.to_thread so the
  loop stays free even outside reindex (transient write windows).
- _get_stale_warning: skip sync LanceDB read during reindex.
- Guard: two-arm regression test (fast-fail vs lock-wait control).
После фикса заморозки реиндекса (1964f1e) осталась ложь в сигналах:
- intel_get_runtime_status показывал '0 chunks | 0 files' во время reindex
  → агент мог решить 'индекс пуст' и запустить ненужный 2-й reindex;
- require_ready_project советовал 'Index is empty → run index_project_dir()'
  когда переиндексация уже идёт;
- format_runtime_status рендерил '⚪ 0 chunks'.

Вариант А (точечная правда, не баннер во все 64 тула):
- layer.intel_get_runtime_status: index_telemetry += status='reindexing',
  reindex_in_progress, reindex_progress_pct, reindex_eta_sec (из
  get_active_reindex_job_id + _enrich_job_response, strict is True +
  isinstance guard от MagicMock-truthy 2026-08-13);
- base.require_ready_project: при reindex → ToolError warning
  '⏳ Index is being reindexed (N%, ETA ~Xm) — retry in a few seconds',
  а не IndexNotReadyError (агент не запустит 2-й reindex);
- ui_formatter.format_runtime_status: '🔄 Reindex in progress (N%)' вместо
  '0 chunks', LED 🟢 (процесс идёт — здоровое состояние).

Guard: 6 новых тестов (runtime_status reindex/normal, require_ready
reindex/empty-control, formatter reindex/без-progress/normal-unchanged).
Live: полный reindex 9003 chunks за 519s — все MCP-вызовы отвечали
мгновенно (постоянный опрос job + search fast-fail).
…ex status' wrapper)

Live-прогон Варианта А показал двойную обёртку: search_code выдавал
'🔴 Error: Failed to check index status: ⏳ Index is being reindexed...' —
наша reindex-ошибка ловилась общим except Exception в require_ready_project
и теряла status='warning' + recoverable=True (ретry-семантику).

Fix: except ToolError: raise BEFORE except Exception — целевые ошибки
проходят насквозь; неожиданные по-прежнему заворачиваются.

Guard: Arm 3 regression — reindex ToolError пробрасывается как есть;
неожиданный ValueError всё ещё заворачивается в 'Failed to check index status'.
Косметический баг 2026-08-26: get_indexer() ставит ProjectState.INDEXING при
пустом индексе, но никто не переводил состояние в READY после завершения
индексации — паспорт вечно показывал 'Project State: INDEXING' и
wait_until_ready ждал до таймаута.

- server_factory._delayed_auto_index: после успешной авто-индексации →
  registry.set_state(READY);
- layer._run_reindex_job: после job.status='completed' → set_state(READY).

Guard: 3 теста (auto-index → READY; skip при непустом индексе → без
set_state; reindex job → READY). Полный pytest 1521 passed, ruff clean.
SymbolIndexAdapter (graph-backed) has no _definitions/_references/_file_to_symbols maps, so incremental index wrote an EMPTY JSON over the populated symbol_index.json (incident 2026-08-26: file empty while 10748 symbols live in memory). Guard: graph-backed instances skip JSON persistence (graph.db is the source of truth) and an empty plain instance must not overwrite a non-empty file. 4 regression tests.
Two-session lab track on the mechanical tool boundary: M1 (telemetry: 5/62 tools ever used), M2 (sub-agent 0/5 MCP calls), M3 (latency matrix), E2-E4 (category router NEGATIVE: search-only ceiling 0.23), E4.1 (graph-arm POSITIVE: 0.433, verify_change 0), E4.2 (concept resolver): deterministic klass-gated concept->symbol registry before lexical extract_symbol + graph-rows facts (graph_fact_text). Real-graph probe: verify_change T9/T29 HIT, facts 4/4 and 3/4. EXPERIMENTS_LOG entries M1-E4.2; README tool/test badges; telemetry pruned per M1 findings.
ARCLUX_AUDIT_2026-08-26.md is a third-party audit artifact (ARCLUX CLI 0.2.0 from another project dir); its tool version is not this project's version, so stale_detector falsely flagged 0.2.0 vs 3.4.0. Exclude the dated artifact (precedent: venv exclude KNOWN_ISSUES 2026-08-12). Config edit invalidated the stale_detector negative-control fixture digest; re-proved via --pin (manifest.json + pin_log.json, TC-10 review record).
SymbolIndex JSON corruption guard live (graph-backed adapter no longer writes empty JSON over populated file; sync to EXT verified md5-identical, 4 regression tests) + E4.2 deterministic klass-gated concept resolver (verify_change T9/T29 HIT on real graph.db, facts 4/4 and 3/4).
Idempotent upsert-by-id tool that mirrors experiments M1-M3/E2-E4.2 (+E4 negativeResult) into MSPortfolio src/data/lab/experiments.json + .ru.json preserving CRLF/indent/ensure_ascii conventions. Verified by portfolio guard: pnpm test tests/lab.test.ts tests/evidence-eval.test.ts 26 passed.
…_change 1.00)

Full 30-task live run: cascade 0.267 -> cascade+graph 0.50 (med 196.8ms, p95 4514ms, target >=0.40/<600ms reached). verify_change 0->1.0 (T9 arm=graph:notify_change, T29 arm=graph:_extract_symbol_name); 9/9 classes >= cascade, no regression. results_E4_1_graph.json regenerated; EXPERIMENTS_LOG/AGENT_DIARY updated; portfolio exp-31 -> confirmed (guard 26 passed).
…d line off-by-one

- Persist SymbolIndex to LanceDB with row-group compaction (E4.1 / Step 1)
- Add graph-stage SymbolIndexAdapter + project-root binding for graph/search/intel tools (Step 2)
- Fix MCP freeze during full reindex: QueueHandler/QueueListener instead of in-loop StreamHandler (root cause: logging._lock contention on stderr pipe)
- Fix off-by-one: tree-sitter 0-based capture points now emit 1-based start_line (340 -> 341); removed compensating +1 in search_tools
- Fix SCM/walk format-parity test encoding old 0-based line; update docs (AGENT_DIARY post-mortems + KNOWN_ISSUES; add pre-existing finalization-hang note)

Verified: live full reindex embedded without server freeze; LanceDB chunks 341/332; full pytest 1553 passed.
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e8e158e-6cc6-4c11-9802-326b753118c6


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ManSio
ManSio merged commit b81e8e1 into main Aug 28, 2026
9 of 13 checks passed
ManSio added a commit that referenced this pull request Sep 10, 2026
…ocs (#32)

* fix(cypher): translate collect() to json_group_array with typed decode

COLLECT(expr) now lowers to json_group_array(expr) FILTER (WHERE expr IS NOT NULL): Neo4j semantics (null-ignored, empty match -> []). collect(*) and nested collect raise explicit ValueError; DISTINCT is rejected by the parser layer. Translator marks collect columns (collect_cols); cypher_executor decodes json.loads only for marked string columns (collision-safe, warning-only on decode failure).

13 new SQL/E2E/error tests incl. decode-collision guard; full pytest 1663 passed / 6 skipped / 91 deselected (verified 5x incl. sanitized-env gate-zero replica); ruff clean; verify_diary 16/0; negative controls: stale_detector PROVEN. Red Team 5/5. Experiments G1/G2 raw-verified on sqlite 3.50.4.

Refs KNOWN_ISSUES 2026-09-07 (collect open -> fixed).

* chore(issues): dedup entries, add temperatures and deadlines

Remove 3 duplicate issue blocks (full version kept), fix false entry counter (11 -> 14) after dedup, set yellow temperature + deadline + owner on open items (VOR lazy-only by 2026-09-15, B4 refactor by 2026-10-01).

* docs(logs): E-S1/E-S2 live-repo results; add .h issue; fix tests badge

- EXPERIMENTS_LOG: E-S1/E-S2 on 6 real top-repos (imports edge-rate
  java 0.867 / php 0.797 / c 0.680 / kotlin 0.853 / dart 0.940 /
  ruby 0.618; calls php 0.813 / ruby 0.562 / c 0.250 / dart 0.080 -
  synthetic "PHP/Ruby/C/Dart calls = 0" defect withdrawn; skeleton
  ASSIGNED_FROM+condition_path thousands of rows outside Python)
- KNOWN_ISSUES: new Open entry - .h headers not indexed
  (SUPPORTED_EXTENSIONS lacks .h; curl 65/300 map_lies mostly .h)
- README: tests badge -> 1663 (real full-suite count: 1663 passed /
  6 skipped / 91 deselected, verified twice on this HEAD)
- telemetry: runtime rotation from MCP tool runs

Refs: docs/research/universal-engine-study/05 sec.3, 08 sec.3,
KNOWN_ISSUES #13 (lazy reindex: symbols +28, graph not rebuilt)

* docs(logs): record Exhibit #23 audit (absent tool call) for continuous verification

* feat(intel): idle background VOR pass via IdleScheduler hook

Verify memory without an agent call: _check_index_health now invokes a
registered hook (set_idle_vor_callback) that runs VerifyOnRead in the
background with budget=250ms and locked()-guard. Uses the shared
_write_lock and get_verifier registry so idle and agent passes
serialize without a second lock. Extract _build_symbol_resolver for
DRY. Closes KNOWN_ISSUES 2026-09-07 (deadline 2026-09-15).

* docs(issues): mark second lazy-only record as Fixed (sync with H1)

* feat(parse): index .h C headers as parseable C files

PARSE_EXTENSIONS now includes .h; the C parser handles .h, env and
import node maps map .h->c/preproc_include. Header files previously
produced no AST imports/calls even though they were vector-indexed
(dart-http curl 65/300 chunks were .h). Closes the E-S1 map_lies gap.

* docs(issues): mark .h header indexing as Fixed (H2, commit 0301fa9)

* chore(cleanup): remove stray test capture file

* chore(cleanup): remove stray commit capture file

* feat(alerts): system_alerts chain stale->starved with one-shot delivery

Add AlertStore (per-project JSON, thread-safe, dedup by kind+payload,
atomic collect_and_clear limit=5). Generate memory_stale on first
STALE transition in notify_change and memory_starved from idle VOR
and intel_get_project_memory. Deliver via format_system_alerts into
intel_get_project_memory and intel_explain_project_state.

Tests: 14 new (AlertStore + formatter); full pytest 1689 passed.

* docs(log): log system_alerts chain probe (exp 2026-09-10)

---------

Co-authored-by: MSCodeBase Agent <[email protected]>
ManSio pushed a commit that referenced this pull request Sep 26, 2026
… review

v1 rejected (5/8 reindex skew, semantic twin of arrival symptom and of used #2). v2 replaced memory-retraction twin (used #13). Final 8 items span distinct families (cache, security, concurrency, docs, CI, observability, query semantics, destructive tool). Token G6 = PASS; semantic review recorded because the token checker cannot see twins.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant