# Dead-Code Triage Gate Fix Evidence

Spec source: `guard-dead-code-triage.guard-dead-code-triage-gate-fix-evidence-compatibility-proof`

## Step A - Repo-wide caller proof for removed `output_run_result`

Command:

```bash
rg -n "output_run_result\(" .
```

Output:

```text
# no matches
```

Command:

```bash
rg -n "output_run_result" --glob "*.py" .
```

Output:

```text
# no matches
```

Command:

```bash
rg -n "output_run_result" tests/
```

Output:

```text
# no matches
```

Command:

```bash
rg -n "output_run_result" .
```

Output:

```text
./plan.yaml:17638:    name: Recheck and remove dead output_run_result export
./plan.yaml:17640:    description: 'Recheck `src/anima/shell/cli_utils.py::output_run_result` for any
./plan.yaml:17649:      - Targeted guard on the changed file no longer reports `dead_export` for `output_run_result`
./plan.yaml:17741:      removed `output_run_result` export, including raw commands and outputs proving
```

Safety rationale:
- Repo-wide code search (`.` root, including `tests/`) found no callable/importable `output_run_result` references.
- Remaining mentions are plan text only; no runtime callers remain.

## Step B - `token_usage` parameter compatibility proof

Spec source:
- `79b4992` removed unused `token_usage` parameter from `handle_model_request_turn`.

Command:

```bash
rg -n "handle_model_request_turn\(" .
```

Output:

```text
./src/anima/shell/agent_interact.py:280:                    exceeded, in_grace_window, _ = handle_model_request_turn(
./src/anima/shell/agent.py:464:            handle_model_request_turn(
./src/anima/shell/agent_budget.py:179:def handle_model_request_turn(
```

Command:

```bash
rg -n "handle_model_request_turn\(" src/anima/shell/agent.py src/anima/shell/agent_interact.py -A8
```

Output:

```text
src/anima/shell/agent_interact.py:280:                    exceeded, in_grace_window, _ = handle_model_request_turn(
src/anima/shell/agent_interact.py-281-                        turn_count + turn_count_local,
src/anima/shell/agent_interact.py-282-                        max_turns,
src/anima/shell/agent_interact.py-283-                        in_grace_window,
src/anima/shell/agent_interact.py-284-                        budget_tracker,
src/anima/shell/agent_interact.py-285-                        instance_id,
src/anima/shell/agent_interact.py-286-                    )
--
src/anima/shell/agent.py:464:            handle_model_request_turn(
src/anima/shell/agent.py-465-                self.turn_count,
src/anima/shell/agent.py-466-                self.max_turns,
src/anima/shell/agent.py-467-                self.in_grace_window,
src/anima/shell/agent.py-468-                self.budget_tracker,
src/anima/shell/agent.py-469-                self.instance_id,
src/anima/shell/agent.py-470-            )
```

Safety rationale:
- Exactly two runtime callers exist and both pass the 5-argument shape expected after signature change.
- No caller passes `token_usage` anymore; no compatibility shim is required.

## Step C - Test hooks/non-changed files + stronger-than-changed-only proof

Command:

```bash
rg -n "clear_config_cache" tests/
```

Output:

```text
# no matches
```

Command:

```bash
rg -n "clear_config_cache" --glob "*.py" .
```

Output:

```text
# no matches
```

Command:

```bash
rg -n "load_global_config\(" src tests
```

Output:

```text
tests/test_model_config.py:129:        # The runner._llm_timeout is set in run() from load_global_config()
src/anima/shell/agent.py:343:        config_result = load_global_config()
src/anima/shell/agent_runner.py:198:        config_result = load_global_config()
tests/test_global_config.py:21:    result = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:32:    result = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:45:    result = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:68:    result = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:90:    result = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:116:    first = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:117:    second = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:129:    result = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
tests/test_global_config.py:144:    result = load_global_config(env={"ANIMA_CONFIG": str(config_path)})
src/anima/shell/cli_commands/tools_cmd.py:70:    config_result = load_global_config()
src/anima/shell/cli_commands/tools_cmd.py:191:    config_result = load_global_config()
src/anima/shell/model_config.py:51:def load_global_config(
src/anima/shell/model_config.py:112:        - Calls load_global_config() internally
src/anima/shell/model_config.py:142:    result = load_global_config(env)
src/anima/shell/cli_utils.py:57:    config_result = load_global_config()
src/anima/shell/agent_factory.py:88:        config_result = load_global_config()
src/anima/shell/cli_commands/run_spawn.py:501:    config_result = load_global_config()
src/anima/shell/cli_commands/run_spawn.py:872:    config_result = load_global_config()
```

Targeted guard (triage surfaces):

```text
invar_guard(path="src/anima/shell/cli_utils.py", changed=false) -> status=passed, files_checked=1, errors=0, warnings=0
invar_guard(path="src/anima/shell/agent_budget.py", changed=false) -> status=passed, files_checked=1, errors=0, warnings=0
invar_guard(path="src/anima/shell/agent.py", changed=false) -> status=passed, files_checked=1, errors=0, warnings=1
invar_guard(path="src/anima/shell/agent_interact.py", changed=false) -> status=passed, files_checked=1, errors=0, warnings=0
invar_guard(path="src/anima/shell/model_config.py", changed=false) -> status=passed, files_checked=1, errors=0, warnings=0
```

Stronger-than-changed-only proof artifact (highest-risk hidden-caller path = config hook removal):

```bash
uvx invar-tools guard --all
```

Output summary (from full JSON output):

```text
status=passed
summary.files_checked=74
summary.errors=0
summary.warnings=39
property_tests.status=passed
```

Note:
- Full output captured in local tool artifact: `.local/share/opencode/tool-output/tool_cc84e8465001WMQVEIYbaH5d4v`.
- RuntimeWarning spam from Hypothesis async coroutine handling is pre-existing and did not change status (guard still `passed`).

## Step D - Warning drift reconciliation (2025-03-07)

### Targeted guard run on shell files

Command:

```bash
uvx invar-tools guard src/anima/shell/agent.py
uvx invar-tools guard src/anima/shell/agent_interact.py
```

Output (agent.py):

```text
status=passed, files_checked=1, errors=0, warnings=2
- function_size line 325: AgentRunner.run exceeds 100 lines
- dead_assign line 805: message_history assigned but never read
```

Output (agent_interact.py):

```text
status=passed, files_checked=1, errors=0, warnings=1
- dead_assign line 368: previous_text_length assigned but never read
```

### Drift analysis

| File              | Evidence (Step C) | Current    | Drift | Status |
| ----------------- | ----------------- | ---------- | ----- | ------ |
| agent.py          | 1 warning         | 2 warnings | +1    | Retained |
| agent_interact.py | 0 warnings        | 1 warning  | +1    | Retained |

### Retained warning justifications

| File | Line | Warning | Justification |
|------|------|---------|---------------|
| agent.py | 325 | function_size | Already in evidence as pre-existing. |
| agent.py | 805 | dead_assign | `message_history` is reassigned each iteration in `_run_agent_loop`. The loop continues indefinitely (polling for pending messages) until either `killed` or `completed` is returned. The final value is never read because the loop either continues or exits via early returns. Escape hatch comment added but detection limitation prevents full suppression. |
| agent_interact.py | 368 | dead_assign | `previous_text_length` is used in sliding-window delta computation (lines 359-360 use it to slice `current_text[previous_text_length:]`). The final value is unused after the `break` statement exits the message iteration loop. This is a false positive detection. Escape hatch comment added but detection limitation prevents full suppression. |

### Code changes

- `src/anima/shell/agent.py`: Added escape hatch comments at lines 802, 804 (dead_assign)
- `src/anima/shell/agent_interact.py`: Added escape hatch comments at line 367-368 (dead_assign)

Commit: bd9717c

Scope control:
- Fix is evidence+code: escape hatch comments added, warnings retained as documented
- No functional changes to code logic
- Warning drift is reconciled via explicit retained-warning justifications

| Symbol | Location | Why retained | Verification basis |
|---|---|---|---|
| `output_spawn_result` | `src/anima/shell/cli_utils.py` | Still used for `spawn` CLI output; only `output_run_result` was dead. | `rg -n "output_spawn_result\(" .` shows call from `src/anima/shell/cli_commands/run_spawn.py:1091`. |
| `handle_model_request_turn` | `src/anima/shell/agent_budget.py` | Active transition helper for max-turns grace path. | `rg -n "handle_model_request_turn\(" .` + call-context output in `agent.py` and `agent_interact.py`. |
| `_CONFIG_CACHE` | `src/anima/shell/model_config.py` | Required by `load_global_config` mtime cache path; only `clear_config_cache` export was dead. | `rg -n "_CONFIG_CACHE" src tests` shows multiple read/write sites inside loader. |
| `load_global_config` | `src/anima/shell/model_config.py` | Public API still used broadly across shell + tests. | `rg -n "load_global_config\(" src tests` shows callers in non-changed files and tests. |

Scope control statement:
- No compatibility cleanup was required beyond evidence correction; caller/test-hook probes did not expose hidden runtime dependencies.
