diff --git a/docs/guide_app_controller.md b/docs/guide_app_controller.md index f4dbb1c3..7904bdee 100644 --- a/docs/guide_app_controller.md +++ b/docs/guide_app_controller.md @@ -60,13 +60,13 @@ When `--enable-test-hooks` is passed, the controller also spins up the HookServe Initializes the controller. Real state created here: -The actual `__init__` (`src/app_controller.py:778-836`) does the following: +The actual `__init__` (`src/app_controller.py:778-1212`) does the following: 1. **Startup timeline anchors** — Captures `_init_start_ts` for the `startup_timeline()` diagnostics. Other timeline anchors are filled in lazily as events occur. -2. **Locks** — Creates 12 thread-safety locks (`_send_thread_lock`, `_disc_entries_lock`, `_pending_*_lock` for comms/tool_calls/history/gui_tasks/dialog/api_event_queue, `_rag_engine_lock`, `_rag_sync_lock`/`_rag_sync_token`/`_rag_sync_dirty` for FR3 coalescing, `_project_switch_lock`/`_project_switch_in_progress`/`_project_switch_pending_path`/`_project_switch_error`). +2. **Locks** — Creates **11** thread-safety locks (`_send_thread_lock`, `_disc_entries_lock`, `_pending_*_lock` for comms/tool_calls/history/gui_tasks/dialog/api_event_queue, `_rag_engine_lock`, `_rag_sync_lock`, `_project_switch_lock`) plus 5 non-lock state fields for the RAG-sync coalescing and project-switch state machine (`_rag_sync_token`/`_rag_sync_dirty`, `_project_switch_in_progress`/`_pending_path`/`_error`). 3. **GUI health state** — `_gui_degraded_reason` and `_last_imgui_assert` (set when `immapp.run` raises `RuntimeError`; see [guide_gui_2.md](guide_gui_2.md#startup-architecture-lazy-imports-profiler-refresh-rate)). -4. **Shared io_pool** — `make_io_pool()` creates a 4-thread `ThreadPoolExecutor` named `controller-io-N`. This is the SOLE background pool for all async work (no `threading.Thread()` calls anywhere else in `src/`). -5. **Warmup manager** — `WarmupManager(self._io_pool, log_to_stderr=log_to_stderr)` with an on-complete callback to stamp `warmup_done_ts`. `defer_warmup=True` defers the actual `start_warmup()` call until the first frame is painted (the desktop GUI pattern; headless mode starts immediately). +4. **Shared io_pool** — `make_io_pool()` creates an **8-thread** `ThreadPoolExecutor` named `controller-io-N` (per `IO_POOL_MAX_WORKERS = 8` in `src/io_pool.py:20`; the io_pool.py module docstring still says "4 worker threads" — that string is stale from a 2026-06-06 4→8 bump and should be fixed separately). This is the SOLE background pool for all async work (no `threading.Thread()` calls anywhere else in `src/`). +5. **Warmup manager** — `WarmupManager(self._io_pool, log_to_stderr=log_to_stderr)` with an on-complete callback to stamp `warmup_done_ts`. `defer_warmup=True` defers the actual `start_warmup()` call until the first frame is painted (the desktop GUI pattern; headless mode starts immediately). The `log_to_stderr` parameter honors `SLOP_WARMUP_DEBUG` env var. 6. **Various flags** — `_warmup_started`, `_pending_fetch_provider`, `_defer_warmup`. **Manager objects** (`preset_manager`, `persona_manager`, `context_preset_manager`, `tool_preset_manager`, `tool_bias_engine`, `history_manager`, `workspace_manager`, `rag_engine`) are **NOT created in `__init__`**. They are lazy attributes accessed via `__getattr__` and created on first reference (typically from `_load_active_project` at `src/app_controller.py:2150` or from `App._post_init` at `src/gui_2.py:492`). @@ -76,7 +76,7 @@ The actual `__init__` (`src/app_controller.py:778-836`) does the following: 2. `src/api_hooks.py:HookHandler.do_GET` / `do_POST` reads from these registries to expose App methods as `/api/gui` `custom_callback` actions. 3. The `sloppy.py` CLI parses `--enable-test-hooks` and passes it to `HookServer` (a separate class, not the controller). -For the actual init flow, read `src/app_controller.py:778-1212` (`__init__`; the long range is mostly `_post_init`-style wiring for the 12 locks, GUI health state, io_pool, warmup manager, and lazy manager defs), `:1606` (`_init_actions`), `:1740` (`init_state`), and `:2150` (`_load_active_project`). +For the actual init flow, read `src/app_controller.py:778-1212` (`__init__`; the 434-line body is locks + io_pool + warmup manager + ~150 lines of internal/Core/UI/Service state initialization, then the `_settable_fields` map (~75 entries) and `_gui_task_handlers` map (~25 hook actions) at the tail), `:1606` (`_init_actions`), `:1740` (`init_state`), and `:2150` (`_load_active_project`). This is the **only** bridge between the GUI's app methods and the external Hook API. If a method is not in `_predefined_callbacks`, external callers cannot invoke it. diff --git a/docs/guide_rag.md b/docs/guide_rag.md index f88e14ba..f9e84bad 100644 --- a/docs/guide_rag.md +++ b/docs/guide_rag.md @@ -434,7 +434,7 @@ For unit tests that don't need real embedding models, the `BaseEmbeddingProvider ## Future Work -- **External RAG Bridge** — Connect to remote vector databases (e.g., a managed Pinecone or Weaviate) via MCP. The `_search_mcp` method is a placeholder for this. +- **External RAG Bridge** — Connect to remote vector databases (e.g., a managed Pinecone or Weaviate) via MCP. The `_search_mcp` method (`src/rag_engine.py:322`) IS a real implementation: when `RAGConfig.vector_store.provider == "mcp"`, `RAGEngine.search()` dispatches to `_search_mcp()` which calls `mcp_client.async_dispatch("rag_search", {"query": ..., "top_k": ...})`. The MCP-bridge config (`mcp_server`, `mcp_tool`) lives on `VectorStoreConfig`. The bridge wires up the rest of the RAG pipeline to a remote vector store; no per-vendor `_init_vector_store` branch is needed because the MCP server owns that. - **Hybrid Search** — Combine dense (vector) retrieval with sparse (BM25) retrieval for better recall on code keywords. - **Re-ranking** — Apply a cross-encoder reranker to the top-k results before injection to improve precision. - **Caching** — Cache query results in memory to avoid re-embedding for repeated questions. diff --git a/docs/reports/docs_sync_test_era_20260610.md b/docs/reports/docs_sync_test_era_20260610.md index acbcf406..5c507dac 100644 --- a/docs/reports/docs_sync_test_era_20260610.md +++ b/docs/reports/docs_sync_test_era_20260610.md @@ -51,7 +51,7 @@ End-state cleanup of the 4-day test-hell saga (regression_fixes → test_infrast | `guide_api_hooks.md` | 4 new warmup endpoints added (`/api/warmup_status`, `/api/warmup_wait`, `/api/warmup_canaries`, `/api/startup_timeline`); new §Warmup API section | | `guide_testing.md` | **CRITICAL**: `tmp_path_factory` (banned) → `tests/artifacts/live_gui_workspace_` (per-run) for `live_gui_workspace` fixture; 8 new sections (Watchdog, Chroma Cache, xdist, Dependencies Gate, MMA/RAG reset_session, etc.) | | `guide_mcp_client.md` | Tool count 45→46, Python AST 15→18; added 4 structural mutator tools (`py_remove_def`, `py_add_def`, `py_move_def`, `py_region_wrap`) | -| `guide_app_controller.md` | Fictional `AppState` dataclass + `register_hooks` method + `enable_test_hooks` param removed; real `__init__` flow documented (timeline anchors, 12 locks, GUI health state, io_pool, warmup manager) | +| `guide_app_controller.md` | Fictional `AppState` dataclass + `register_hooks` method + `enable_test_hooks` param removed; real `__init__` flow documented (timeline anchors, **11 locks + 5 non-lock state fields**, GUI health state, **8-thread** io_pool, warmup manager) | | `Readme.md` | WorkspaceProfile description + guide_gui_2 line refs updated | ### End-state cleanup (4 tracks archived)