# MCP Config Drift Diagnostic & Sanctioned Repair Runbook (#672)

This document describes the diagnostic framework for detecting configuration drift between the active IDE MCP configuration (`~/.gemini/antigravity-ide/mcp_config.json`) and the offline/global canonical configuration (`~/.gemini/config/mcp_config.json`), and establishes the **sanctioned repair runbook**.

## Background & Problem Statement

Offline tools like `test_mcp_conn.py` test the global configuration (`~/.gemini/config/mcp_config.json`) via `subprocess.Popen`. However, the active IDE/client namespace uses `~/.gemini/antigravity-ide/mcp_config.json`. When required Gitea role servers (`gitea-author`, `gitea-reviewer`, `gitea-merger`, `gitea-reconciler`, `gitea-controller`, `gitea-tools`) are missing or carry mismatched profile environments in the active IDE config:

1. Offline tests pass (`test_mcp_conn.py` green).
2. The IDE client returns `EOF` / `transport closed` when attempting role-scoped mutations.
3. Operators misdiagnose missing server definitions as stale runtimes, leading to forbidden `pkill` attempts (#630) or `mtime` hacks (#655).

## Diagnostic Tool: `mcp_config_drift.py`

Run the diagnostic tool directly to compare configurations:

```bash
python3 mcp_config_drift.py --json
```

Or specify custom config locations:

```bash
python3 mcp_config_drift.py \
  --active-config ~/.gemini/antigravity-ide/mcp_config.json \
  --global-config ~/.gemini/config/mcp_config.json
```

### Key Diagnostic Outputs

- `in_sync`: Boolean indicating if all required Gitea role servers exist in the active IDE config with matching profile declarations.
- `missing_role_servers`: List of role servers present in global config but missing from active IDE config.
- `profile_mismatches`: List of profile environment mismatches per server.
- `reasons`: Explicit, human-readable list of drift causes.

All returned payloads automatically redact secret tokens, DSNs, Authorization headers, and private keys.

---

## Sanctioned Repair Path (Step-by-Step)

When `mcp_config_drift.py` reports drift (`in_sync: false`), execute the following **sanctioned repair steps**:

1. **Backup Active IDE Config:**
   ```bash
   cp ~/.gemini/antigravity-ide/mcp_config.json ~/.gemini/antigravity-ide/mcp_config.json.bak
   ```
2. **Patch Active IDE Config:**
   Copy the missing Gitea role server JSON blocks (`gitea-author`, `gitea-reviewer`, etc.) from `~/.gemini/config/mcp_config.json` into `~/.gemini/antigravity-ide/mcp_config.json`.
3. **Reconnect via IDE/Client:**
   Use the IDE / client UI reconnection control (or restart the IDE client app).
4. **Verify Active Namespace Health:**
   Invoke `gitea_whoami` (and optional `gitea_resolve_task_capability`) through the active IDE client on each required role namespace.

---

## FORBIDDEN Repair Actions (#630 / #655)

The following actions are **strictly forbidden** for config drift repair:

- ❌ **`pkill` or manual daemon process kill commands:** Process kills cause contamination and break active session leases.
- ❌ **`mtime` touch edits:** Artificial mtime modifications mask stale runtimes without updating configuration.
- ❌ **Source code edits:** Mutating python tool logic to bypass missing server entries.
- ❌ **Session-state edits:** Direct database or lock-file state mutation.

---

## Final Report Guidelines

A workflow final report **must not** rely on offline `test_mcp_conn.py` output alone. Final reports must include active-config evidence from live `gitea_whoami` calls on the active IDE namespaces.
