# Sprint 8a Complete Specification — Token Optimization

## Problem Statement

GodotIQ MCP tools return output too large for Claude Code's ~200k token context window. Real example: `asset_registry` on a project with 670 models generates 140k characters from a single call. `scene_map(detail="full")` on an 876-node scene generates similar output. This makes GodotIQ unusable on real projects — the agent exhausts its context window in 4 minutes.

## Objective

After this sprint:
- No tool returns more than **2,000 chars** with `detail="brief"`
- No tool returns more than **8,000 chars** with `detail="normal"`
- `detail="full"` is the only level that can return unlimited output
- **Default is "normal"** for all tools
- Every tool in the system accepts a `detail` parameter for API consistency

## Current State (From Research)

### Existing Infrastructure
- **output_limit.py** already exists with `apply_output_limit(result, detail, list_keys)` — handles dict-based truncation with binary search
- **Config system** has `default_detail: "normal"` setting and `config.get_default_detail()`
- **17 of 32 tools** already have `detail` parameter
- **13 tools** need `detail` added
- **1 tool** (`impact_check`) has `detail` param misused as change description — needs renaming

### Tools Needing Changes

#### Group A: Add `detail` parameter (13 tools)
| Tool | Category | Output Risk | Notes |
|------|----------|-------------|-------|
| suggest_scale | Assets | SMALL | No-op detail (always small output) |
| impact_check | Code | MEDIUM | Rename existing `detail` → `change_description`, add proper `detail` |
| placement | Spatial | SMALL | No-op detail |
| screenshot | Bridge | N/A | Binary output, no-op detail |
| run | Bridge | SMALL | No-op detail |
| editor_context | Bridge | MEDIUM | Could have many open scenes |
| node_ops | Bridge | MEDIUM | Can batch many operations |
| script_ops | Bridge | SMALL | No-op detail |
| file_ops | Bridge | HIGH | Can return large file lists/search results |
| input | Bridge | MEDIUM | Side-effect tracking |
| watch | Bridge | MEDIUM | Variable watch state |
| undo_history | Bridge | MEDIUM | Deep undo stacks |
| save_scene | Bridge | SMALL | No-op detail |
| camera | Bridge | SMALL | No-op detail |

#### Group B: Tune existing `detail` behavior (17 tools)
- Ensure all existing detail implementations use `apply_output_limit()`
- Ensure char limits are enforced (brief≤2000, normal≤8000)
- No functional changes unless needed to meet limits

### Decisions Made (From Interview)

1. **Keep `apply_output_limit()`** as primary mechanism — don't rewrite output formats per tool
2. **Add `detail` to ALL tools** for API consistency, even small/fixed-output tools (no-op is fine)
3. **Rename `impact_check.detail`** → `change_description`, add proper `detail` param
4. **Enhance `output_limit.py`** with simpler string-based `truncate_output()` alongside existing dict-based function
5. **Modify tool implementations** as needed to meet limits, but keep all existing tests passing
6. **Brief docstring mention** for detail param: one line per tool
7. **Python-side filtering** for bridge tools — Godot sends full data, Python truncates
8. **Use existing test fixtures** for integration tests

## Implementation Scope

### 1. Enhance output_limit.py
Add `truncate_output(text: str, detail: str, tool_name: str) -> str` function for string-based truncation alongside the existing dict-based `apply_output_limit()`.

### 2. Add `detail` to 13 remaining tools
For each tool:
- Add `detail: str = "normal"` parameter
- Add one-line docstring mention
- For tools with variable output: apply `apply_output_limit()` at return
- For tools with fixed/small output: parameter exists but behavior unchanged
- For bridge tools: filter Python-side after receiving Godot response

### 3. Rename impact_check parameter
- `detail: str = ""` → `change_description: str = ""`
- Add new `detail: str = "normal"` for output verbosity
- Update any callers/tests

### 4. Tune existing detail implementations
- Verify all 17 existing tools respect the char limits
- Adjust any that exceed brief=2000 or normal=8000

### 5. Testing
For each modified tool, add:
1. Test brief output size: `len(result) < 3000`
2. Test normal output size: `len(result) < 10000`
3. Test default is "normal"
4. Integration test: combined workflow under 30k chars total

### Priority Order
1. `asset_registry` (140k chars → 2k brief) — highest impact
2. `scene_map` (huge on large scenes)
3. `scene_tree` (same issue)
4. `ui_map` (same issue)
5. All remaining tools

## Files to Modify
- `src/godotiq/tools/output_limit.py` — add truncate_output()
- `src/godotiq/tools/assets/__init__.py` — suggest_scale
- `src/godotiq/tools/code/__init__.py` — impact_check rename
- `src/godotiq/tools/spatial/__init__.py` — placement
- `src/godotiq/tools/bridge/__init__.py` — all bridge tools
- `tests/test_tools/` — new test files

## Files NOT to Touch
- `godot-addon/` — GDScript files
- `.mcp.json`, `.godotiq.json` — config files
- Existing test files — only add new tests
