# Hermes Diagnostics — Performance Audit

## Skills Manifest Bloat

The skills index (`~/.hermes/.skills_prompt_snapshot.json`) is injected into the system prompt's stable tier. With many enabled skills, this can balloon to **1.5MB+ (~386K tokens)**.

```bash
wc -c ~/.hermes/.skills_prompt_snapshot.json
```
>1MB = severe bloat. Target: <500KB.

**Count enabled skills:**
```bash
python3 -c "
import yaml, os
with open('/home/rurouni/.hermes/config.yaml') as f:
    cfg = yaml.safe_load(f)
disabled = set(cfg.get('skills', {}).get('disabled', []))
for root, dirs, files in os.walk('/home/rurouni/.hermes/skills'):
    for f in files:
        if f == 'SKILL.md':
            name = os.path.basename(os.path.dirname(os.path.join(root, f)))
            if name not in disabled and not name.startswith('.'):
                sz = os.path.getsize(os.path.join(root, f))
                print(f'{name:45s} {sz:>7,d}B')
" | sort -t'B' -k1 -rn | head -20
```

**If >1MB or >40 enabled skills:** Target 20-25 active skills. Niche skills remain loadable via `skill_view()`.

## tools.stub_mode (Hermes v0.13+)
Reduces per-call tool schema overhead by ~46% (PR #48622). Always check:
```bash
grep 'stub_mode' ~/.hermes/config.yaml || echo "NOT SET — enable with: hermes config set tools.stub_mode true"
```

## Context Compression Health (Local Model Edge Case)
```bash
grep -A5 'compression:' ~/.hermes/config.yaml | grep -A5 'auxiliary'
```

**If `auxiliary.compression.provider` is `auto` or `custom:local`:** Local models often fail at structured summarization. **Fix:**
```yaml
auxiliary:
  compression:
    provider: deepseek
    model: deepseek/deepseek-v4-flash
    timeout: 120
```

## Dashboard WebSocket / Event-Loop Stall

**Symptoms in `gui.log`:**
```
ws write slow (loop stalled >10.0s)
```
Repeating every 10 seconds. Eventually:
```
ws send failed peer=X.X.X.X:YYYYY error_type=WebSocketDisconnect
```

**Restart the dashboard:**
```bash
fuser -k 9119/tcp
/home/rurouni/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main dashboard --port 9119 --host 0.0.0.0 --insecure
```

Prevent systemd conflict:
```bash
systemctl --user stop hermes-dashboard.service
systemctl --user disable hermes-dashboard.service
```

**Verify:** `curl -s http://localhost:9119/api/status` → JSON with `gateway_state: running`.

## Config Version Drift
```bash
grep '_config_version:' ~/.hermes/config.yaml
```
Compare against `hermes --version`. If behind by 2+, run `hermes update`.

## Provider Health Check
```bash
hermes status 2>&1 | grep -A50 "API Keys" | head -25
grep -E "rate-limited|exhausted|429|402|credits" ~/.hermes/logs/errors.log 2>/dev/null | tail -5
grep -A2 'fallback_model:' ~/.hermes/config.yaml
grep -A1 'fallback_providers:' ~/.hermes/config.yaml
```

## Memory Limits
```bash
grep -A4 '^memory:' ~/.hermes/config.yaml
echo "MEMORY.md: $(wc -c < ~/.hermes/memories/MEMORY.md) / $(grep memory_char_limit ~/.hermes/config.yaml | awk '{print $2}')"
echo "USER.md: $(wc -c < ~/.hermes/memories/USER.md) / $(grep user_char_limit ~/.hermes/config.yaml | awk '{print $2}')"
```

**⚠️ CRITICAL:** When USER.md or MEMORY.md exceeds its char limit, memory writes are SILENTLY REJECTED. No error surfaced.

- Default: `memory_char_limit: 1600`, `user_char_limit: 1000`
- Recommended: `memory_char_limit: 3000`, `user_char_limit: 2500`
- Fix: `hermes config set memory.memory_char_limit 3000 && hermes config set memory.user_char_limit 2500`

## Context Length Cache
```bash
grep -i "<model-name>" ~/.hermes/context_length_cache.yaml
```
Known values: `deepseek-v4-flash`: 1,048,576; `gpt-5.x-codex`: 272,000; `stepfun/step-3.7-flash`: 256,000.

## Complete Audit Methodology
See `references/comprehensive-audit-template.md` for full multi-phase audit: environment inspection, token quantification, skills/memory/prompt audits, competitive analysis, research delegation patterns, and report structure.
