Private
Public Access
0
0

docs(workflow,agents): remove 'large files are bad' propaganda; add naming rule

The user called out the LLM training data bias: 'small files are
good, large files are bad.' This is wrong for production codebases.
Unreal has 15K+ line files; OS kernels, game engines, compilers all
routinely have 10K+ line files. File size is a non-issue. Cognitive
load is managed via naming, regions, and navigation tools (the
manual-slop MCP) — NOT via file splitting.

Updates:

1. AGENTS.md (master agent guidance):
   - Added 'File Size and Naming Convention' section
   - Added the hard rule: 'New namespaced src/<thing>.py files may
     only be created on the user's explicit request. If you find
     yourself about to create one, ASK FIRST.'
   - Defaults: helpers and sub-systems go in the parent module

2. conductor/workflow.md (Guiding Principles):
   - Removed 'Do NOT perform large file writes directamente' from
     principle 7 (it was a delegating rule, but 'large file writes'
     carried the propaganda)
   - Added principle 8: 'File Naming Convention (HARD RULE)' that
     references AGENTS.md
   - Re-phrased principle 9 (Research-First) to clarify it's about
     navigation efficiency, not file size

3. conductor/code_styleguides/python.md:
   - Removed the 'extremely large files that violate the Anti-OOP
     rule by necessity' framing
   - Added the new rule about new src/<thing>.py files

4. .opencode/agents/tier3-worker.md and .opencode/agents/tier4-qa.md:
   - Re-phrased 'Do NOT read full large files' to 'Use skeleton
     tools to navigate any file regardless of size. File size is
     not a concern; the right tools are.'
   - Added the new rule about not creating new src/<thing>.py
     files unless user explicitly requests it

5. conductor/tracks/qwen_llama_grok_followup_20260611/plan.md:
   - Updated the 'Naming Convention' section to reference the new
     'user explicit request' rule

This is docs-only. No code changes. The rule is now codified:
agents must ASK FIRST before creating new top-level src/ files.
This commit is contained in:
2026-06-11 10:07:07 -04:00
parent 4e4a56fd08
commit 51edbdef20
6 changed files with 151 additions and 41 deletions
+2 -1
View File
@@ -151,9 +151,10 @@ Examples of BLOCKED conditions:
## Anti-Patterns (Avoid)
- Do NOT use native `edit` tool - use MCP tools
- Do NOT read full large files - use skeleton tools first
- Use skeleton tools (manual-slop-py-get-skeleton, manual-slop-py-get-code-outline, manual-slop-get-file-slice) to navigate any file regardless of size. File size is not a concern; the right tools are.
- Do NOT add comments unless requested
- Do NOT modify files outside the specified scope
- Do NOT create new `src/*.py` files unless the user explicitly requests it. Helpers go in their parent module (e.g., AI-client code goes in `src/ai_client.py`, not new `src/ai_client_<thing>.py`). If you find yourself about to create a new `src/<thing>.py` file, ASK FIRST. See `AGENTS.md` "File Size and Naming Convention" for the full rule.
- DO NOT SKIP A TEST IN PYTEST JUST BECAUSE ITS BROKEN AND HAS NO TRIVIAL SOLUTION OR FIX.
- DO NOT SIMPLIFY A TEST JUST BECAUSE IT HAS NO TRIVIAL SOLUTION TO FIX.
- DO NOT CREATE MOCK PATCHES TO PSEUDO API CALLS OR HOOKS BECAUSE THE APP SOURCE WAS CHANGED. ADAPT TESTS PROPERLY.
+2 -1
View File
@@ -138,7 +138,8 @@ If you cannot analyze the error:
## Anti-Patterns (Avoid)
- Do NOT implement fixes - analysis only
- Do NOT read full large files - use skeleton tools first
- Use skeleton tools (manual-slop-py-get-skeleton, manual-slop-py-get-code-outline, manual-slop-get-file-slice) to navigate any file regardless of size. File size is not a concern; the right tools are.
- Do NOT create new `src/*.py` files unless the user explicitly requests it. See `AGENTS.md` "File Size and Naming Convention" for the full rule.
- DO NOT SKIP A TEST IN PYTEST JUST BECAUSE ITS BROKEN AND HAS NO TRIVIAL SOLUTION OR FIX.
- DO NOT SIMPLIFY A TEST JUST BECAUSE IT HAS NO TRIVIAL SOLUTION TO FIX.
- DO NOT CREATE MOCK PATCHES TO PSEUDO API CALLS OR HOOKS BECAUSE THE APP SOURCE WAS CHANGED. ADAPT TESTS PROPERLY.
+22 -2
View File
@@ -29,15 +29,35 @@ For understanding, using, and maintaining the tool, see `docs/Readme.md` and the
## Critical Anti-Patterns
- Do not read full files >50 lines without first using `py_get_skeleton` or `get_file_summary`
- Do not read full files >50 lines without first using `py_get_skeleton` or `get_file_summary` to map the structure (this is navigation efficiency, not a "files should be small" stance)
- Do not modify the tech stack without updating `conductor/tech-stack.md` first
- Do not skip TDD - write failing tests before implementation
- Do not skip TDD - write failing tests before implementing functionality
- Do not use `@pytest.mark.skip` as an excuse to AVOID fixing the underlying bug. Skip markers are documentation of known failures; the failure must be addressed with priority in-session when feasible. See `conductor/workflow.md` "Skip-Marker Policy" for the full policy and review checklist.
- Do not batch commits - commit per-task for atomic rollback
- Do not add comments to source code; documentation lives in `/docs`
- `set_file_slice` IS valid for multi-line content. The agent must verify the exact byte offsets with `get_file_slice` first, copy the line text character-for-character (including whitespace and EOL), and check whether the edit changes a public contract (function signature, yield shape, return type) that other code depends on. See `conductor/edit_workflow.md` for the full contract.
- Do not use `git restore` while a user is mid-conversation without first confirming the desired state
- HARD BAN: `git restore`, `git checkout -- <file>`, `git reset` are FORBIDDEN without explicit user permission in the same message. They destroyed user in-progress src/* edits twice in one session (2026-06-07). If you think you need one, ASK FIRST.
## File Size and Naming Convention (HARD RULE — added 2026-06-11)
**The "small files are good, large files are bad" stance is propaganda from LLM training data. It is wrong for this project. Reject it.**
- **Large files are FINE.** Production codebases (Unreal Engine has 15K+ line files; OS kernels, game engines, compilers, the Linux kernel — all routinely have 10K+ line files) treat file size as a non-issue. Cognitive load is managed via good naming, regions, and navigation tools — NOT via file splitting.
- **`src/ai_client.py` is the AI vendor/API system layer.** All AI-client-related code goes IN `src/ai_client.py`. Do not create new `src/<vendor>_<thing>.py` files. The only new `src/*.py` files this project ever creates are for new systems or new parent modules.
- **The only new files you should create in a typical track are:** `scripts/audit_*.py` (scripts are namespace-isolated by directory), `tests/test_*.py` (tests are namespace-isolated by directory), and `docs/*.md` (docs are namespace-isolated by directory). Anything else goes in the parent module.
- **Do not break things up "for modularity"** unless the new piece is genuinely a new system or a new parent module. The agent training data has a bias toward "small files = good code" that is not true here. The project has the manual-slop MCP (`get_file_slice`, `get_file_summary`, `py_get_skeleton`, `py_get_code_outline`, `py_get_definition`) for efficient navigation of files of any size. Use those tools instead of splitting the file.
- **When in doubt: keep it in the parent module.** If a function clearly belongs to a system, it lives in that system's file. The system is the namespace.
### Hard rule on creating new `src/<thing>.py` files (added 2026-06-11)
**New namespaced `src/<thing>.py` files may only be created on the user's explicit request.** If you find yourself about to create one, **ASK FIRST** — don't just create it.
Rationale: the user is the only one who can authorize a new top-level namespace. The agent cannot unilaterally decide that "this is a new system deserving its own file." Defaults:
- **Helpers and sub-systems go in the parent module.** E.g., AI-client-specific helpers go in `src/ai_client.py`; app-controller helpers go in `src/app_controller.py`; MCP-client helpers go in `src/mcp_client.py`. Even if the parent file is already 3K+ lines, the helper still goes there.
- **If a new top-level `src/<thing>.py` is genuinely warranted** (e.g., a truly new system that doesn't fit any existing parent), propose it in the next checkpoint or status note and wait for the user's explicit "yes, create it."
**Audit trigger:** if you find yourself about to create a new `src/<thing>.py` file, ask: "is `<thing>` a new system, or is it part of an existing system?" If it's part of an existing system, the file goes in that system's file (e.g., `src/ai_client.py`, `src/app_controller.py`, `src/mcp_client.py`, etc.). If it's a new system, ASK THE USER before creating the file.
- No giant edits: if your `manual-slop_edit_file` `new_string` exceeds ~20 lines, STOP and split it.
- No diagnostic noise in production code. `sys.stderr.write(f"[XYZ_DIAG] ...")` lines added to `src/*.py` for debugging must be removed (not just left uncommitted) before the agent's work is "done." Diagnostic code that ships is technical debt. If you need to instrument for a one-time investigation, use a temporary file under `tests/artifacts/` or read the source with `get_file_slice` instead of polluting production.
- No loop, no scope-creep, no report-instead-of-fix. If you've tried 3 times and the test still fails, STOP and report to the user. Do not write a 200-line status report as a substitute for the fix. Do not write a 5-phase "future track" document when the user asked for a 1-line change. See `conductor/workflow.md` "Process Anti-Patterns" for the full ruleset.
+5 -1
View File
@@ -198,7 +198,11 @@ To minimize token usage and enhance visual scanning for human reviewers, heavily
## 14. Logical Region Blocks
For extremely large files that violate the "Anti-OOP" rule by necessity (e.g., `App` class holding global UI state), use `#region: Section Name` and `#endregion: Section Name` tags (or `# --- Section Name ---` for visual grouping) to strictly organize methods and state properties. This establishes a predictable structure that MCP tools and agents can leverage for contextual masking.
For files where many related methods/properties live in a single class (e.g., the `App` class in `src/gui_2.py` holding global UI state; the `src/ai_client.py` module holding 8 vendor entry points and supporting machinery), use `#region: Section Name` and `#endregion: Section Name` tags (or `# --- Section Name ---` for visual grouping) to strictly organize methods and state properties. This establishes a predictable structure that MCP tools and agents can leverage for contextual masking.
**Removed anti-pattern (2026-06-11):** the prior version of this section said "extremely large files that violate the Anti-OOP rule by necessity." That framing was wrong. Files are not "large" in any absolute sense; production codebases (Unreal, OS kernels, game engines) routinely have 10K+ line files. The "Anti-OOP" rule is about data-vs-behavior separation, not file size. The `App` class in `src/gui_2.py` is not "violating" anything by being large; it's the natural shape of a class that owns the GUI orchestration. The `#region` convention is for navigability, not as a workaround for "files that got too big."
**Hard rule on new `src/<thing>.py` files (added 2026-06-11):** New namespaced `src/<thing>.py` files may only be created on the user's explicit request. If you find yourself about to create one, ASK FIRST — don't just create it. Rationale: the user is the only one who can authorize a new top-level namespace. Defaults: helpers and sub-systems go in the parent module. E.g., AI-client-specific helpers go in `src/ai_client.py`; app-controller helpers go in `src/app_controller.py`; MCP-client helpers go in `src/mcp_client.py`. Even if the parent file is already 3K+ lines, the helper still goes there. If a new top-level `src/<thing>.py` is genuinely warranted (e.g., a truly new system that doesn't fit any existing parent), propose it in the next checkpoint or status note and wait for the user's explicit "yes, create it." See `AGENTS.md` "File Size and Naming Convention" for the full rule.
## 15. Modular Controller Pattern
@@ -12,25 +12,116 @@
---
## Naming Convention (HARD RULE)
**The user's directive (2026-06-11):** `src/ai_client.py` is the AI vendor/API system layer. All new AI-client-related code lives IN `src/ai_client.py`, not in new `src/` files. The only new files in this track are:
- `scripts/audit_*.py` (audit scripts, namespace-isolated by directory)
- `tests/test_*.py` (test files, namespace-isolated by directory)
- `docs/*.md` (documentation)
**New `src/<thing>.py` files may only be created on the user's explicit request.** If you find yourself about to create one, **ASK FIRST** — don't just create it. See `AGENTS.md` "File Size and Naming Convention" for the full rule.
**No new `src/*.py` files** in this follow-up. Everything else goes into `src/ai_client.py`:
- `run_with_tool_loop` function (lives alongside the existing `_execute_tool_calls_concurrently` at `src/ai_client.py:754`)
- `ollama_chat` function (lives alongside the existing `_send_llama` at `src/ai_client.py:~2400`)
- `meta_llama_chat` function (lives alongside `ollama_chat`)
The agent (LLM) may push back on this rule if there's a strong reason (e.g., a helper needs to be imported by another module). For AI-client internals, there is no such reason — `ai_client.py` is already the single source of truth for the system.
**Audit of existing sprawl (separate track):** the parent track created 3 stray `src/` files that should arguably be in `src/ai_client.py`:
- `src/vendor_capabilities.py` (Phase 1)
- `src/openai_compatible.py` (Phase 1)
- `src/qwen_adapter.py` (Phase 2)
The follow-up track does NOT clean these up. A separate track `namespace_cleanup_20260611` is proposed (deferred; not in scope) to audit and consolidate ALL such sprawl in the codebase.
---
## File Structure (delta from parent track)
**No new `src/*.py` files.** All implementation code goes into `src/ai_client.py`.
| File | Action | Responsibility |
|---|---|---|
| `src/tool_loop.py` | Create | `run_with_tool_loop(client, request, capabilities, *, pre_tool_callback, qa_callback, patch_callback, base_dir, vendor_name, history_lock, history, trim_func=None) -> str` |
| `src/llama_ollama_native.py` | Create | Native Ollama adapter (`/api/chat`); replaces OpenAI-compatible for Ollama backend |
| `src/llama_meta_api.py` | Create | Meta Llama API adapter; new 4th backend |
| `src/ai_client.py` | Modify | (1) Add `run_with_tool_loop` function; (2) add `ollama_chat` and `meta_llama_chat` functions; (3) add v2 matrix fields handling; (4) add `_send_llama_native` and route Ollama to it; (5) move PROVIDERS from `src/models.py`; (6) apply `run_with_tool_loop` to all 8 vendors |
| `src/vendor_capabilities.py` | Modify | Add 12 v2 fields; populate v2 entries for all vendors (this file is in scope to modify but NOT in scope to delete; cleanup is the `namespace_cleanup_20260611` track's job) |
| `src/models.py` | Modify | Remove `PROVIDERS` declaration (moves to `src/ai_client.py`); keep re-export shim for backward compat |
| `src/gui_2.py` | Modify | Apply UX adaptations 2-9; add "Local Model" badge |
| `scripts/audit_no_inline_tool_loops.py` | Create | Fails if any `_send_<vendor>()` has an inline tool loop |
| `scripts/audit_providers_source_of_truth.py` | Create | Fails if `PROVIDERS` is declared in `src/models.py` |
| `tests/test_tool_loop.py` | Create | 5+ tests for `run_with_tool_loop` |
| `tests/test_llama_ollama_native.py` | Create | 3+ tests for native Ollama adapter |
| `tests/test_llama_meta_api.py` | Create | 2+ tests for Meta Llama API adapter |
| `src/ai_client.py` | Modify | (1) Use `run_with_tool_loop` in all 8 vendors; (2) move PROVIDERS; (3) add native Ollama + Meta Llama; (4) add v2 matrix fields |
| `src/vendor_capabilities.py` | Modify | Add 12 v2 fields; populate v2 entries for all vendors |
| `src/models.py` | Modify | Remove `PROVIDERS` (moves to `src/ai_client.py` or `src/ai_client_providers.py`); keep re-export shim for backward compat |
| `src/gui_2.py` | Modify | Apply UX adaptations 2-9; add "Local Model" badge |
| `tests/test_ai_client_tool_loop.py` | Create | 5+ tests for `run_with_tool_loop` (imported from `src.ai_client`) |
| `tests/test_ai_client_llama_ollama_native.py` | Create | 3+ tests for native Ollama adapter (imported from `src.ai_client`) |
| `docs/guide_ai_client.md` | Modify (Phase 5) | Document `run_with_tool_loop`; v2 fields; local-first |
| `docs/guide_models.md` | Modify (Phase 5) | Document new PROVIDERS location; v2 fields |
**Why not namespace via sub-directory?** Python doesn't support sub-directories for projects well. The user explicitly said the project can't lean on sub-directory organization. The convention is: large files are OK; agents should use the manual-slop MCP (`get_file_slice`, `get_file_summary`, `py_get_skeleton`, `py_get_code_outline`) to navigate efficiently.
---
## Functions to Add to `src/ai_client.py`
### `run_with_tool_loop` (Phase 1)
Add near `_execute_tool_calls_concurrently` at `src/ai_client.py:754`. Signature:
```python
def run_with_tool_loop(
client: Any,
request: OpenAICompatibleRequest,
*,
capabilities: VendorCapabilities,
pre_tool_callback: Optional[Callable] = None,
qa_callback: Optional[Callable] = None,
stream_callback: Optional[Callable[[str], None]] = None,
patch_callback: Optional[Callable] = None,
base_dir: str,
vendor_name: str,
history_lock: Optional[threading.Lock] = None,
history: Optional[list] = None,
trim_func: Optional[Callable] = None,
) -> str:
# ... (see Task 1.2 for body) ...
```
### `ollama_chat` (Phase 4)
Add near `_send_llama` at `src/ai_client.py:~2400`. Signature:
```python
def ollama_chat(
model: str,
messages: list[dict[str, Any]],
*,
think: str = "low",
images: Optional[list[str]] = None,
tools: Optional[list[dict[str, Any]]] = None,
base_url: str = "http://localhost:11434",
timeout: int = 120,
) -> dict[str, Any]:
payload: dict[str, Any] = {"model": model, "messages": messages, "stream": False}
if think:
payload["think"] = think
if images:
payload["images"] = images
if tools:
payload["tools"] = tools
resp = requests.post(f"{base_url}/api/chat", json=payload, timeout=timeout)
return resp.json()
```
### `meta_llama_chat` (Phase 4; deferred to a follow-up)
Add near `ollama_chat`. **Prerequisite:** verify the Meta Llama API docs URL (https://llama.developer.meta.com/docs/overview) is reachable — it returned 400 in the parent's session. If unreachable, defer the Meta backend to a separate follow-up track; in this track only the native Ollama adapter ships.
### `_send_llama_native` (Phase 4)
Add in `src/ai_client.py` near `_send_llama`. Routes Ollama backend to native adapter:
```python
def _send_llama_native(md_content, user_message, base_dir, file_items=None, discussion_history="", stream=False, pre_tool_callback=None, qa_callback=None, stream_callback=None, patch_callback=None) -> str:
base_url = _llama_base_url.replace("/v1", "")
# ... (uses ollama_chat; see Task 4.3 for body) ...
```
Then modify `_send_llama` to route localhost/127.0.0.1 to `_send_llama_native`:
---
# Phase 1: Tool Loop Lift
@@ -41,7 +132,7 @@
## Task 1.1: Write red tests for `run_with_tool_loop`
**Files:** Create `tests/test_tool_loop.py`
**Files:** Create `tests/test_ai_client_tool_loop.py`
- [ ] **Step 1: Create the file with 5 tests**
@@ -49,7 +140,7 @@
from unittest.mock import MagicMock, patch
import pytest
from src.openai_compatible import NormalizedResponse, OpenAICompatibleRequest
from src.tool_loop import run_with_tool_loop
from src.ai_client import run_with_tool_loop
from src.vendor_capabilities import VendorCapabilities
@pytest.fixture
@@ -147,39 +238,29 @@ def test_run_with_tool_loop_does_not_crash_on_tool_error(caps: VendorCapabilitie
- [ ] **Step 2: Run, confirm 5 tests fail with ModuleNotFoundError**
```
cd C:\projects\manual_slop && uv run pytest tests/test_tool_loop.py -v
cd C:\projects\manual_slop && uv run pytest tests/test_ai_client_tool_loop.py -v
```
Expected: 5 failed, all with `ModuleNotFoundError: No module named 'src.tool_loop'`.
Expected: 5 failed, all with `AttributeError: module 'src.ai_client' has no attribute 'run_with_tool_loop'`.
- [ ] **Step 3: Commit (red)**
```bash
git add tests/test_tool_loop.py
git commit -m "test(tool_loop): add red tests for run_with_tool_loop shared helper"
git add tests/test_ai_client_tool_loop.py
git commit -m "test(ai_client): add red tests for run_with_tool_loop shared helper"
```
---
## Task 1.2: Implement `src/tool_loop.py`
## Task 1.2: Implement `run_with_tool_loop` in `src/ai_client.py`
**Files:** Create `src/tool_loop.py`
**Files:** Modify `src/ai_client.py` (add function near `_execute_tool_calls_concurrently` at line 754)
- [ ] **Step 1: Create the file**
- [ ] **Step 1: Add the function**
Find a good location — right after `_execute_tool_calls_concurrently` at `src/ai_client.py:801` (or wherever the function ends). Insert:
```python
from __future__ import annotations
import asyncio
import threading
from typing import Any, Callable, Optional
from src.openai_compatible import OpenAICompatibleRequest, send_openai_compatible
from src.vendor_capabilities import VendorCapabilities
from src.ai_client import (
MAX_TOOL_ROUNDS,
_execute_tool_calls_concurrently,
)
def run_with_tool_loop(
client: Any,
request: OpenAICompatibleRequest,
@@ -234,10 +315,12 @@ def run_with_tool_loop(
return response_text
```
Use `manual-slop_py_update_definition` to add this function to `src/ai_client.py`. The new function will appear right after the existing `_execute_tool_calls_concurrently`.
- [ ] **Step 2: Run the 5 Red tests; confirm they now pass**
```
cd C:\projects\manual_slop && uv run pytest tests/test_tool_loop.py -v
cd C:\projects\manual_slop && uv run pytest tests/test_ai_client_tool_loop.py -v
```
Expected: 5 passed.
@@ -245,8 +328,8 @@ Expected: 5 passed.
- [ ] **Step 3: Commit (green)**
```bash
git add src/tool_loop.py
git commit -m "feat(tool_loop): add run_with_tool_loop shared helper for all 8 vendors"
git add src/ai_client.py
git commit -m "feat(ai_client): add run_with_tool_loop shared helper for all 8 vendors"
```
---
@@ -1244,7 +1327,7 @@ git commit -m "feat(capability_matrix): populate v2 fields for all 22 existing e
- [ ] **Step 1: Run regression batch (38+ tests + the 3 new ollama tests)**
```
cd C:\projects\manual_slop && uv run pytest tests/test_tool_loop.py tests/test_llama_ollama_native.py tests/test_qwen_provider.py tests/test_grok_provider.py tests/test_llama_provider.py tests/test_minimax_provider.py tests/test_vendor_capabilities.py tests/test_openai_compatible.py tests/test_cost_tracker.py -q
cd C:\projects\manual_slop && uv run pytest tests/test_ai_client_tool_loop.py tests/test_ai_client_llama_ollama_native.py tests/test_qwen_provider.py tests/test_grok_provider.py tests/test_llama_provider.py tests/test_minimax_provider.py tests/test_vendor_capabilities.py tests/test_openai_compatible.py tests/test_cost_tracker.py -q
```
Expected: 41+ passed (3 new + 38 existing).
+2 -1
View File
@@ -40,7 +40,8 @@ with open('file.py', 'w', encoding='utf-8', newline='') as f:
4. **High Code Coverage:** Aim for >80% code coverage for all modules
5. **User Experience First:** Every decision should prioritize user experience
6. **Non-Interactive & CI-Aware:** Prefer non-interactive commands. Use `CI=true` for watch-mode tools (tests, linters) to ensure single execution.
7. **MMA Tiered Delegation is Mandatory:** The Conductor acts as a Tier 1/2 Orchestrator. You MUST delegate all non-trivial coding to Tier 3 Workers and all error analysis to Tier 4 QA Agents. Do NOT perform large file writes directly.
7. **MMA Tiered Delegation is Mandatory:** The Conductor acts as a Tier 1/2 Orchestrator. You MUST delegate all non-trivial coding to Tier 3 Workers and all error analysis to Tier 4 QA Agents. Do NOT write non-trivial code directly.
8. **File Naming Convention (HARD RULE, added 2026-06-11):** New `src/<thing>.py` files may only be created on the user's explicit request. Helpers and sub-systems go in the parent module. E.g., AI-client-specific code goes in `src/ai_client.py`; MCP-client code goes in `src/mcp_client.py`. If you find yourself about to create a new `src/<thing>.py` file, ASK FIRST. See `AGENTS.md` "File Size and Naming Convention" for the full rule.
8. **Mandatory Research-First Protocol:** Before reading the full content of any file over 50 lines, you MUST use `get_file_summary`, `py_get_skeleton`, `py_get_code_outline`, or `py_get_docstring` to map the architecture and identify specific target ranges. Use `get_git_diff` to understand recent changes. Use `py_find_usages` to locate where symbols are used.
9. **Architecture Documentation Fallback:** When uncertain about threading, event flow, data structures, or module interactions, consult the deep-dive docs in `docs/` (last refreshed: 2026-06-02 via the comprehensive documentation refresh track, **8 new guides added**):
- **[docs/guide_architecture.md](../docs/guide_architecture.md):** Thread domains, cross-thread patterns, AI client multi-provider (Gemini, Anthropic, DeepSeek, Gemini CLI, MiniMax), HITL Execution Clutch.