two¢ents

The traps

Each of these is a setting or a mechanism you can check tonight.

1 · Allow-all overrides everything

The gateway checks access in a fixed order: per-platform allow-all → DM-pairing approved list → platform allowlists → global allowlist → global allow-all → deny. Allow-all comes first. Turn it on to skip pairing while testing Discord, and every allowlist below it stops mattering. On a public server, someone who joined nine seconds ago can then command an agent with a terminal toolset and discord_admin. Test with pairing from day one. Only use allow-all when everyone who can reach the bot is someone you’d hand your laptop to.

2 · Without write approval, prompt injection sticks

Stages 2 to 4 of the prompts rely on the agent rewriting its own skills with skill_manage. With skills.write_approval off, a member’s message, or a pasted “changelog” hiding instructions, can get the agent to edit a SKILL.md or a scripts/ file. A bad reply is gone once sent. A poisoned skill stays and runs again. A community bot reads untrusted text all day, so keep the gate on, read the diffs, and keep approvals.mode on manual until things settle.

3 · Memory is one screen long

MEMORY.md caps at 2,200 characters, USER.md at 1,375. That’s all the memory sent with every prompt. Ask it to remember 300 people and each new fact silently pushes out an old one. Keep MEMORY.md as an index (“notes live in the community-notes skill”), put member facts in per-member files, and look up history with session_search. If you reworded stage 1, this is why the bot keeps forgetting petra.

4 · session_search is keyword search

It’s SQLite FTS5 full-text matching, with no embeddings or vector store, whatever an AI summary told you. It finds “webhook” and misses “the callback thing broke”. Have the bot write notes in the community’s own words (stage 2). If you need semantic recall, add an external memory provider such as Mem0 or Honcho.

5 · Faking per-member memory leaks

Hermes doesn’t split memory by group-chat member. USER.md describes you, the owner. Tell the bot to “remember things about members” without the notes skill, and those facts go into the shared memory sent with every conversation. That’s how a WhatsApp DM detail turns up in public Discord. The “never quote a member’s file” rule helps, but the model follows it by convention and nothing enforces it. Don’t store anything you couldn’t stand to see misfiled.

6 · Always-on costs

A terminal agent bills when you type. A gateway agent bills when anyone in three busy channels types, and each call carries the memory and skill context. On a frontier model, a busy Discord week becomes a large invoice, so put a cheap model on community duty. Nous Portal’s web_search and browser tools are metered, which is partly why the changelog skill uses curl. A weekly cron calling a metered tool is a subscription you didn’t know you’d signed up for.

7 · Scripts run as you

On the default local terminal backend, execute_code and skill scripts are unsandboxed and run as your user, next to ~/.hermes/.env and your SSH keys. Switch the terminal backend to docker: the container drops all capabilities, sets no-new-privileges and caps processes, and the docs say the container itself is the security boundary. Keep approvals.deny globs too. The built-in blocklist catches rm -rf / and little else.

8 · No mod tier

Access is all or nothing. Mods paired to your instance can do everything the bot can, discord_admin and the terminal included. A prompt rule like “only obey Dana for rewards” is a polite request. It blocks nothing. Give mods their own profile: hermes profile create mods gives them a separate config with its own toolsets, allowlist, approvals.deny and gateway. Keep the powerful profile paired only to you.

Disagree? Pin a note on it →