Agent stack build plans · № 2 · Hermes community manager

The traps

Every one of these is a mechanism, not a mood. Most are settings you can check tonight.

1 · Allow-all is first in the auth check order

The gateway checks access in a fixed order: per-platform allow-all → DM-pairing approved list → platform allowlists → global allowlist → global allow-all → deny. Notice what’s first. Flip allow-all on a platform — say, to skip pairing friction while testing Discord — and every allowlist you carefully maintain below it is dead code. On a public server that means any member, including the one who joined nine seconds ago, can command an agent that holds a terminal toolset and your discord_admin powers. Test with pairing from day one; allow-all is for a bot whose only reachable users are people you’d hand your laptop.

2 · An open skills.write_approval turns prompt injection into persistence

Stages 2–4 of the prompts work precisely because the agent can rewrite its own skills with skill_manage. Leave skills.write_approval off and that power is on a hair trigger: a member’s message — or a pasted “changelog” that’s really instructions — can talk the agent into editing a SKILL.md or a scripts/ file, and unlike a bad chat reply, a poisoned skill persists and re-runs. In a community bot the untrusted-input firehose is the whole product, so: gate on, read the diffs, and keep approvals.mode on manual until the novelty wears off.

3 · The bot cannot remember your community — by design

MEMORY.md caps at 2,200 characters, USER.md at 1,375. That’s the whole always-injected memory: roughly one screen of text. An agent asked to “remember” a 300-person community will thrash — each new fact evicts an old one, silently. The fix is the architecture, not a bigger prompt: MEMORY.md holds only the index (“notes live in the community-notes skill”), member facts live in per-member files, and history is queried on demand with session_search. If you skipped stage 1’s wording, this is why the bot keeps forgetting petra.

4 · session_search is keyword search, not semantic

Past-session recall runs on SQLite FTS5 — full-text matching, no embeddings, no vector store (whatever an AI summary told you). It finds “webhook” if someone typed “webhook”, not if they typed “the callback thing broke”. Two consequences: teach the bot (stage 2) to file notes using the community’s own vocabulary, and if you genuinely need semantic recall, that’s what the external memory-provider plug-ins (Mem0, Honcho, and friends) are for — a deliberate add-on with its own moving parts, not a default you forgot to enable.

5 · Per-member memory in groups is not a feature, and pretending it is leaks

Nothing in Hermes shards memory per group-chat member; USER.md models you, the owner. If you skip the notes skill and just tell the bot “remember things about members”, member facts get smeared into the one shared memory that’s injected into every conversation — which is how a detail from a WhatsApp DM surfaces, helpfully, in public Discord. The notes skill plus its “never quote a member’s file” rule is the containment. It’s a convention the model follows, not an enforcement boundary — so still don’t store anything you wouldn’t want misfiled.

6 · The always-on bill, and the metered extras

A terminal agent bills when you type. A gateway agent in three active channels bills when anyone does — every handled message is an inference call, plus the injected memory and skill context on each one. Busy Discord weeks are the difference between pocket change and a real invoice on a frontier model; put a cheap model on community duty. Separately: Nous Portal’s web_search/browser tools are metered, paid add-ons. The changelog skill in this plan uses its own curl script partly for that reason — a cron job that quietly calls a metered search tool weekly is a subscription you didn’t know you signed.

7 · Reward scripts run as you, unless you sandbox them

execute_code and skill scripts on the default local terminal backend are not sandboxed — they run with your user, on the machine that holds ~/.hermes/.env and your SSH keys. For a bot marinating in untrusted community text, switch the terminal backend to docker: Hermes’s hardened container drops all capabilities, sets no-new-privileges, and caps processes — the docs’ own line is that on docker, the container itself is the security boundary. Also keep approvals.deny globs for the unforgivables; the built-in hardline blocklist catches rm -rf /, not your imagination.

8 · There is no mod tier, and faking one ends badly

Access is in-or-out. If you pair your mods onto the same instance as yourself, they can command everything the bot can do — including discord_admin and the terminal. Don’t simulate roles with prompt rules (“only obey Dana for rewards”); that’s a politeness, not a permission. The real mechanism is profiles: hermes profile create mods gives mods a fully separate config — own toolsets, own allowlist, own approvals.deny, own gateway — and the powerful profile stays paired to you alone.

Disagree? Pin a note on it →