# Section 3: Rename impact_check Parameter + Add detail to Code Tools

## Overview

The `impact_check` tool in `src/godotiq/tools/code/__init__.py` currently misuses the `detail` parameter as a free-text description of the intended change (not output verbosity). This section renames that parameter to `change_description` and adds a proper `detail` parameter for controlling output size via `apply_output_limit()`.

This is the most complex single-tool change in Sprint 8a because it involves a parameter rename (MCP schema change), a result dict field rename, and adding truncation behavior.

**Depends on:** Section 1 (output_limit.py enhancements — input validation for unknown detail values).

## File to Modify

`/Users/salvatorefarruggio/Desktop/godotiq/src/godotiq/tools/code/__init__.py`

Only the `impact_check` tool within this file is modified. The other code tools (`dependency_graph`, `signal_map`, `validate`) already have proper `detail` support and are not touched.

## Tests First

These tests go in `/Users/salvatorefarruggio/Desktop/godotiq/tests/test_tools/test_detail_levels.py`. They use the existing `session` fixture from `conftest.py` and call `_build_impact_check` directly (the same pattern used in the existing `test_impact_check.py`).

### impact_check parameter rename tests

```python
# Test: impact_check accepts change_description parameter
# Call _build_impact_check(session, file, action, target, change_description="some change")
# Verify it returns a valid result dict (no error).

# Test: returned dict contains "change_description" field (not "detail")
# Call _build_impact_check with change_description="rename add_cash to add_money"
# Assert "change_description" in result
# Assert result["change_description"] == "rename add_cash to add_money"
# Assert the key "detail" is NOT in result (the old field name is gone)

# Test: safe_alternative message uses change_description content correctly
# Call _build_impact_check with action="add_parameter", target="add_cash",
#   change_description="tax_rate"
# Assert "tax_rate" appears in result["safe_alternative"]
# (This verifies the string interpolation was updated from the old `detail` variable)
```

### impact_check output verbosity tests

```python
# Test: impact_check detail="brief" output under 3000 chars
# Call _build_impact_check with detail="brief"
# json.dumps(result) length should be under 3000

# Test: impact_check detail="normal" output under 10000 chars
# Call _build_impact_check with detail="normal"
# json.dumps(result) length should be under 10000

# Test: impact_check default detail is "normal"
# Call _build_impact_check WITHOUT detail parameter
# Verify result is constrained to normal limits

# Test: apply_output_limit adds truncation metadata when callers list is large
# Create a session with many fake dependent scripts
# Call _build_impact_check with detail="brief"
# Verify result contains "output_truncated" and/or the callers list is shortened
```

## Implementation Details

### 1. Rename `detail` to `change_description` in `_build_impact_check`

The internal function `_build_impact_check` currently has this signature:

```python
def _build_impact_check(
    session: GodotIQSession,
    file: str,
    action: str,
    target: str = "",
    detail: str = "",
) -> dict:
```

Change it to:

```python
def _build_impact_check(
    session: GodotIQSession,
    file: str,
    action: str,
    target: str = "",
    change_description: str = "",
    detail: str = "normal",
) -> dict:
```

Key changes within the function body:

1. **All references to the old `detail` variable that mean "change description"** must be renamed to `change_description`. Specifically:

   - The `if detail:` check in the `add_parameter` safe_alternative logic becomes `if change_description:`
   - The string interpolation `safe_alternative = f"Use default value: {target}({detail} = <default>)"` becomes `safe_alternative = f"Use default value: {target}({change_description} = <default>)"`

2. **The returned result dict** currently has `"detail": detail`. Change this to `"change_description": change_description`. The key in the returned dict changes from `"detail"` to `"change_description"`.

3. **Add `apply_output_limit()` call** before returning the result dict. The result dict contains two lists that can grow: `"callers"` and `"signal_impact"`. The return statement changes from:

   ```python
   return {
       "file": res_path,
       "action": action,
       "target": target,
       "detail": detail,
       ...
   }
   ```

   to:

   ```python
   result = {
       "file": res_path,
       "action": action,
       "target": target,
       "change_description": change_description,
       ...
   }
   return apply_output_limit(result, detail, list_keys=["callers", "signal_impact"])
   ```

4. **The `detail` parameter** (the new one for output verbosity) has default `"normal"` and is passed to `apply_output_limit()`. It is NOT used in any conditional logic within the function. The tool always builds the full result; truncation happens via `apply_output_limit()`.

### 2. Update the MCP tool wrapper `godotiq_impact_check`

The public async wrapper currently has:

```python
async def godotiq_impact_check(
    file: str,
    action: str,
    target: str = "",
    detail: str = "",
    ctx: Context = None,
) -> dict:
```

Change to:

```python
async def godotiq_impact_check(
    file: str,
    action: str,
    target: str = "",
    change_description: str = "",
    detail: str = "normal",
    ctx: Context = None,
) -> dict:
```

The docstring must clearly distinguish the two parameters:

```python
"""Predict what breaks BEFORE making a change. ...

Args:
    file: Path to .gd file being modified.
    action: "modify_function", "rename_signal", "add_parameter", etc.
    target: The function/signal/class being changed.
    change_description: Free-text description of the intended change (used in safe_alternative suggestions).
    detail: Output verbosity — "brief" (summary), "normal" (default), or "full" (everything).
"""
```

The call to `_build_impact_check` must pass both parameters:

```python
return _build_impact_check(
    session, file, action, target,
    change_description=change_description,
    detail=detail,
)
```

### 3. Behavioral Changes Summary

This change introduces three observable behavioral differences:

1. **MCP schema change (breaking):** The tool parameter `detail` (free-text) is replaced by `change_description` (free-text) and `detail` (verbosity enum). LLM agents read schemas each session, so this is safe.

2. **Result dict field rename:** The returned dict key `"detail"` becomes `"change_description"`. Any code that reads `result["detail"]` from `impact_check` output will break — but since consumers are LLM agents that parse dynamically, this is acceptable.

3. **New truncation fields:** When output exceeds limits, the result dict may now include `output_truncated`, `truncation_notice`, and `callers_total` / `signal_impact_total` fields. These are informational metadata added by `apply_output_limit()`.

### 4. Existing Tests Compatibility

The existing `test_impact_check.py` calls `_build_impact_check` with positional arguments. Since `change_description` is in the same positional slot (5th argument) as the old `detail` parameter, these calls continue to work correctly without modification. The value will be received as `change_description` instead of `detail`.

Verify that no existing test reads `result["detail"]` — this key no longer exists. The existing tests only read `result["callers"]`, `result["action"]`, `result["risk"]`, `result["safe_alternative"]`, etc.

### 5. No Changes to Other Code Tools

`dependency_graph`, `signal_map`, and `validate` already have proper `detail` parameter support with `apply_output_limit()`. They are not modified in this section. They are reviewed in Section 6 (verify existing implementations).
