# Hermes Performance + Token-Efficiency Audit Reference

Use this when the user asks for a deep Hermes environment audit or says to optimize/fix Hermes end-to-end.

## High-ROI audit sequence

1. **Back up before touching config/state**
   - Copy `~/.hermes/config.yaml`, memory files, skills, and relevant systemd unit files into a timestamped backup directory.
   - Preserve a config checksum so rollback is obvious.

2. **Update and migrate first**
   - Run `hermes update`.
   - Run `hermes config check` / `hermes config migrate` / `hermes doctor`.
   - Do not diagnose stale config behavior before confirming current config version.

3. **Check service health and stale units**
   - `systemctl --user list-units --type=service --type=path --failed`
   - `systemctl --user list-unit-files | grep -i hermes`
   - If the setup uses a stable local router like llama-swap, old per-model path watchers/services (`hermes-config.path`, `hermes-model-switch.service`) may be obsolete. Remove/disable only after verifying local routing is through the stable router and the user wants llama-swap canonical.

4. **Validate local router, not old per-model ports**
   - Probe the stable endpoint, e.g. `curl http://127.0.0.1:9292/v1/models`.
   - Confirm all configured local model IDs are visible.
   - Avoid reviving direct per-model systemd ports when the router is healthy.

5. **Fix fallback config shape**
   - Current fallback chain code expects `fallback_providers` entries as dicts with `provider` and `model`.
   - Bad/stale shape:
     ```yaml
     fallback_providers:
       - custom:local-llm-(llama-swap)
     ```
   - Good shape:
     ```yaml
     fallback_providers:
       - provider: custom:local-llm-(llama-swap)
         model: qwen36-35b-mtp
     ```
   - Legacy `fallback_model` may still work, but normalize to `fallback_providers` for determinism.

6. **Reduce default tool schema surface**
   - Measure effective tool count with `model_tools.get_tool_definitions()` using current `toolsets` and `agent.disabled_toolsets`.
   - Broad default bundles like `hermes-cli` are convenient but expensive because every schema is sent to the model.
   - Lean default for normal chat/coding:
     ```yaml
     toolsets:
       - file
       - terminal
       - skills
       - memory
       - session_search
       - todo
       - clarify
     ```
   - Add browser/web/vision/image/delegation/cron only for sessions that need them.

7. **Prune the skill index, not just files on disk**
   - Count enabled skills and total enabled `SKILL.md` chars.
   - Disable rarely used/non-core skills under `skills.disabled` instead of deleting them.
   - Keep class-level umbrella skills active; move large session-specific detail to `references/`.

8. **Tune Telegram streaming for flood control**
   - Recurring log lines like `Telegram flood control, waiting 260.0s` mean streaming edits are too aggressive.
   - Increase:
     ```yaml
     streaming:
       edit_interval: 1.5
       buffer_threshold: 80
     ```
   - For very long audit/build sessions, consider disabling Telegram streaming entirely.

9. **Remove null/empty config sections**
   - Dashboard/TUI warning: `config.yaml has empty section(s)`.
   - Remove null sections such as `max_concurrent_sessions:` if no nested settings exist.

10. **Dashboard remote/no-auth preference**
   - For Ray's trusted LAN/Tailscale setup, dashboard service should include `--host 0.0.0.0 --insecure` when zero-auth is desired.
   - Verify with `/api/status`: `auth_required: false`.

11. **Clear build-tool advisories safely**
   - If `hermes doctor` reports `ui-tui` build-tool advisory, run `npm audit --omit=dev` first.
   - If prod audit is clean and full audit shows a transitive dev advisory, `npm audit fix` inside `~/.hermes/hermes-agent/ui-tui` is usually enough.
   - Verify with `npm audit --json` and keep only lockfile changes if no source changes are needed.

12. **Final verification**
   - `hermes doctor`
   - `hermes status --all`
   - `systemctl --user is-active hermes-gateway hermes-dashboard`
   - `systemctl --user list-units --failed | grep hermes || true`
   - Dashboard `/api/status`
   - Local router `/v1/models`
   - Effective tool schema count

## Phase 1b: YAML Shape Checks (runtime gate)

After the file parses, scan for these common broken shapes:

| Symptom | Bad YAML pattern | Fix |
|---------|------------------|-----|
| Gateway ignores ALL overrides | Any block mapping error at line N | Fix the mapping; restart gateway |
| Model switch fails to persist | `platforms: {}` then nested keys under same parent | Remove stray `platforms: {}` |
| Config drift after tool write | CLI wrote array as JSON string (`'[\"a\",\"b\"]'`) | Use Python `yaml.dump` for list/array paths |
| Skills not loading | `skills.disabled` is a string, not list | Verify with `python3 -c "yaml.safe_load(open(...))['skills']['disabled']"` → must be `list` |

**Critical: `display.platforms` trap** — platform streaming keys (`discord:`, `telegram:`) must be
under `platforms:` at the top level of the file, NOT nested inside `display:`. A previous
audit mistakenly introduced `platforms: {}` inside `display:` while also keeping top-level
`platforms:` with real entries, creating an invalid YAML block that silently discarded the
entire config. Check BOTH locations; they are not the same key.

## Phase 2: Token Quantification

- Do not use `patch`/direct writes against `~/.hermes/config.yaml` if guards block it. Use `hermes config` where possible or a deliberate atomic YAML writer after backup.
- `tempfile` in `/tmp` can fail atomic `os.replace()` across devices. Create temp files in the same directory as `config.yaml` or use a safe move pattern.
- `hermes doctor --fix` may not fix npm advisories; inspect the workspace-specific audit.
- Do not declare optional missing API keys as failures. They only matter if the user wants those toolsets/providers.
- If slimming `toolsets`, expect browser/web/image/cron/delegation tools to disappear from default sessions. That is the intended token-saving tradeoff; users can re-enable for targeted sessions/profiles.
