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.