# Invar Remediation 2026-03-09 - Gate Evidence Blocker Repair

Spec source: `invar-remediation-2026-03-09.fix-gate-evidence-blockers`

## 1) Freeze Snapshot Reconciliation and Drift Resolution

### Reviewed/frozen snapshot (authoritative for gate packet)

- Frozen snapshot commit: `cc9cd5bc6790d18915abf977d89db56e8282b8b7`
- Reviewed snapshot commit: `cc9cd5bc6790d18915abf977d89db56e8282b8b7`

Proof command (gate packet references this exact commit):

```bash
git show d5c8072:plan.yaml | rg -n "freeze-gate-snapshot|PR: cc9cd5bc6790d18915abf977d89db56e8282b8b7|git rev-parse HEAD -> cc9cd5bc6790d18915abf977d89db56e8282b8b7"
```

Observed lines include:

- `- PR: cc9cd5bc6790d18915abf977d89db56e8282b8b7`
- `- Run: git rev-parse HEAD -> cc9cd5bc6790d18915abf977d89db56e8282b8b7`

### Drift observed after freeze

```bash
git rev-parse HEAD
git diff --name-only cc9cd5bc6790d18915abf977d89db56e8282b8b7..HEAD
```

Observed:

- Current HEAD: `828e150f2a1b70cb5cf467c33f1029e30dd0e339`
- Drifted files since frozen snapshot:
  - `plan.yaml`
  - `src/anima/core/schemas/enums.py`
  - `src/anima/core/schemas/errors.py`
  - `src/anima/core/tool_policy.py`
  - `src/anima/shell/agent_budget.py`
  - `src/anima/shell/cli_commands/lifecycle_cmds.py`
  - `src/anima/shell/ctl.py`
  - `src/anima/shell/ctl_tools.py`

### Drift resolution (explicit)

- Gate packet authority is pinned to reviewed/frozen commit `cc9cd5bc6790d18915abf977d89db56e8282b8b7`.
- Re-gate must validate evidence against that snapshot; post-freeze drift above is out-of-snapshot and must not be treated as part of the frozen packet.
- Independent re-gate precheck command:

```bash
test "$(git rev-parse HEAD)" = "cc9cd5bc6790d18915abf977d89db56e8282b8b7"
```


## 2) Retest Category Accounting (same full guard config, now complete)

Guard configuration reused:

```bash
uv run invar guard --all
```

Evidence extraction command:

```bash
python3 - <<'PY'
import json
from collections import Counter
with open('/tmp/invar_guard_all.json') as f:
    data = json.load(f)
ctr = Counter(item.get('rule') for item in data.get('static', {}).get('findings', []))
for k in [
    'shell_pure_logic',
    'file_size_warning',
    'function_size',
    'review_suggested',
    'redundant_type_contract',
    'duplicate_escape_reason',
    'shell_too_complex',
    'dead_param',
    'partial_contract',
    'contract_quality_ratio',
]:
    print(f"{k}={ctr.get(k, 0)}")
PY
```

Category accounting:

| Family | Prior retest count | Current count | Status | Notes |
| --- | ---: | ---: | --- | --- |
| shell_pure_logic | 16 | 0 | pass | remains cleared |
| file_size_warning | 6 | 5 | residual | reduced by 1 |
| function_size | 2 | 0 | pass | remains cleared |
| review_suggested | 1 | 0 | pass | remains cleared |
| redundant_type_contract | 6 | 0 | pass | remains cleared |
| duplicate_escape_reason | 0 | 0 | pass | remains cleared |
| shell_too_complex | n/a (omitted before) | 3 | residual | now explicitly accounted |
| dead_param (regression guard) | 0 | 0 | pass | remains cleared |
| partial_contract (regression guard) | 0 | 0 | pass | remains cleared |
| contract_quality_ratio (regression guard) | 0 | 0 | pass | remains cleared |

Guard summary from same run:

- `status=passed`
- `errors=0`
- `warnings=8`
- `infos=3`
- `files_checked=83`


## 3) Residual Findings Classification (complete)

All residual families from `static.findings`:

| Family | Count | Classification | Rationale | Blocking? |
| --- | ---: | --- | --- | --- |
| file_size_warning | 5 | tech_debt | Near-threshold file-size warnings; no static errors; non-correctness pressure for incremental decomposition | NO |
| dead_assign | 3 | should_fix | Potentially confusing dead local assignments; clarity/maintainability issue, not a gate blocker at current severity | NO |
| shell_too_complex | 3 | accepted (narrow) | Branch-heavy shell resolver paths are currently bounded and verified under passing guard; accepted as narrow debt pending later extraction | NO |

Residual locations (for independent re-gate):

- `file_size_warning`: `src/anima/core/sandbox.py`, `src/anima/shell/cli.py`, `src/anima/shell/cli_commands/talk_runtime.py`, `src/anima/shell/cli_commands/cleanup_cmds.py`, `src/anima/shell/cli_commands/tools_cmd.py`
- `dead_assign`: `src/anima/shell/agent.py:855`, `src/anima/shell/cli_commands/talk_runtime.py:526`, `src/anima/shell/cli_commands/inspect_collect.py:555`
- `shell_too_complex`: `src/anima/shell/memory/resolver.py:25`, `src/anima/shell/memory/resolver.py:57`, `src/anima/shell/memory/resolver.py:89`


## 4) Scope Confirmation

- This repair updates gate artifacts/evidence only.
- No source remediation batch was reopened in this step.
