Hermes family OS · 3 of 6 · architecture
Profiles, not roles
The one correction that makes this build work — and the honest map of what’s built in, what you wire, and what you build.
First, the correction
The circulating AI answers describe “an admin profile for the household lead plus restricted roles for members” inside one Hermes agent, sharing “a family vault”. As of v0.19.0, none of that exists as described:
- Gateway auth is binary. A sender is allowed or denied —
the check order is per-platform allow-all → DM-pairing approved list →
platform allowlists → global allowlist → global allow-all → deny. An
unknown sender who DMs the agent gets a one-time code; the owner runs
hermes pairing approve <platform> <code>. There are no admin-vs-restricted tiers inside one instance. - Differentiated access is done with profiles.
hermes profile create <name>(with--clone/--clone-from) creates a fully separate agent: its own config, model, credentials, toolsets, memory, skills, and sessions — and its own gateway (hermes gateway listshows them per profile). - The “family vault” is not a Hermes feature.
It’s a directory you create, that skills in both profiles read and
write. The real mechanisms in reach are protected paths (Hermes already
shields
~/.ssh/and.envfiles) andHERMES_WRITE_SAFE_ROOTfor confining writes.
So the family OS is: one full-capability profile the lead pairs with, plus trimmed member profiles, plus shared surfaces (the group chat and the vault directory). That’s the whole trick.
The map
householdFull toolsets: homeassistant, cronjob, skills, memory, browser (Portal, metered). Holds HASS_TOKEN, MCP creds. Paired: the lead. Serves the family group.sam-agentTrimmed toolsets, approvals.deny globs, docker terminal backend, own allowlist (Sam only), own memory. No house credentials — separation by construction.~/family-vault/: groceries.md, members/ notes, house docs. Not a Hermes feature — a convention your skills enforce, with HERMES_WRITE_SAFE_ROOT fencing member writes.household only.~/.hermes/cron/, delivery to any platform. Runs the 07:00 brief, 16:00 groceries, 21:30 close.ha_list_entities, ha_get_state, ha_list_services, ha_call_service. Full build: smart home plan.Three flows worth tracing
Morning brief with clash resolution
Cron fires at 07:00 in the household profile → the job’s
prompt tells the agent to read today’s events through the calendar MCP
tools before composing → it finds the 08:25/08:30 overlap → posts one
message to the group proposing a swap → a human reacts → done. Clash
resolution is not a feature you install; it’s the agent’s
job, stated in the cron prompt, and it degrades gracefully — worst
case you get a brief without conflict-checking.
Grocery consolidation
A skill (you build it in prompts, stage 4) tells
both profiles: when someone mentions running out of something, append to
~/family-vault/groceries.md. The 16:00 cron dedupes the file,
pushes to Notion via MCP, and posts a summary. The optional last hop —
pre-loading a supermarket cart with browser_navigate /
browser_click / browser_type on Browser Use’s
cloud Chromium — is metered (paid Nous Portal), fragile against site
redesigns, and stops hard before payment.
Per-member context in the group (the honest version)
Hermes memory is MEMORY.md (2,200-char cap) +
USER.md (1,375 chars) per profile, injected into the system
prompt, plus full-text search over past sessions. Per-sender memory in
group chats is not documented — so “the agent knows Dele hates
coriander” is glue: a members/ folder in the vault, one
note file per person, maintained by a skill, read on demand. It works well;
it’s just yours to build and yours to cap.
Security boundaries, explicitly
- Credential isolation is the point of profiles. HASS_TOKEN,
calendar and Notion credentials, Portal access:
household’s.envonly. Member profiles physically lack them, and Hermes strips env from child processes anyway (terminal.env_passthroughis an explicit opt-in). - Docker backend for anything members can trigger. Hermes’s
hardened docker terminal drops all capabilities, sets no-new-privileges, caps at
256 processes and a 512 MB tmpfs. The docs’ own framing: the container
is the security boundary.
execute_codeon thelocalbackend is not sandboxed — never leave a member profile on it. - Approvals per profile.
approvals.mode(smart/manual/off) plusapprovals.denyfnmatch globs on the member side; the hardline blocklist (fork bombs,rm -rf /) holds even in yolo mode, but don’t make it do the work.