When something runs other agents
Most things that read your code are one agent. Some of them are not.
Hermes, OpenClaw and Ruflo each sit between a person and a runtime. They route work, define roles, install hooks, spawn background workers, and in two cases hand work to agents on machines you are not looking at. On a roster they look like one row. At the seam they are several, so the readout says how many:
AI AGENTS claude-code, hermes, ruflo
HARNESSES hermes, ruflo 9 principals
hermes: 3 roles
ruflo: 5 roles · runs claude-code, codex-cli · 2 hook files · federated across machinesNine principals behind two rows. That number is read off the directories those products scaffolded, not taken from a count in anybody's README.
Memnox does not replace what they enforce
This is worth being exact about, because the opposite claim is easy to make and wrong. All three ship real controls:
Memnox reads those rather than ignoring them. A tool Hermes excluded is not reported as reachable through Hermes, and the count it removed is printed beside the smaller number so it does not read as a scan that missed something:
MCP SERVERS crm, github
6 more hidden by the host's own filter, so they are not counted hereAn OpenClaw agent whose config denies exec genuinely has no shell, and the scan
does not give it one.
What none of them can see
Each protects its own runtime. None of them can see:
- The other two. Hermes' allow-list has no opinion about what OpenClaw is doing in the same repository at the same moment.
- The disk underneath.
~/.aws/credentials,~/.ssh/id_ed25519, theghlogin, the browser profile that still holds your sessions. A tool policy governs tools. - The shell all three share. An agent that can run one reaches everything you reach, whatever its tool list says.
- What a set of permitted tools adds up to.
Combined capability
A tool allow-list checks one call at a time. That is the right thing to check, and it is not the only thing.
COMBINED CAPABILITY (no single tool does this)
! hermes: customer data can leave, in one session
crm.read_customer → crm.create_customer_export → slack.send_customer_fileEvery tool in that chain is ordinary. Every one of them passes review on its own. Holding all three is an exfiltration path, and no per-call filter is shaped to notice it.
Chains are read deterministically, from tool names only: an acquire step
(read_, get_, list_, query_, fetch_, download_), an optional
package step (export_, archive_, backup_, snapshot_), and an emit
step (send_, post_, publish_, upload_, forward_) — grouped by the
subject they act on, so read_customer plus send_invoice is two jobs and
read_customer plus send_customer_report is one path.
A chain is only printed when no single step is destructive on its own. The destructive ones are already counted elsewhere, and the whole point of this block is the calls that individually look fine.
Where each one is found
Detection is by config file, never by a process list, and every row names the path that proved it.
Read from
Hermes
OpenClaw
Ruflo
Two rules hold for all three. A config that will not parse grants nothing — OpenClaw writes JSON with comments, so the reader strips what JSON does not allow and tries again, and anything still unreadable is treated as absence rather than as a reason to widen what we claim. A value never leaves the file it was in — what travels is the name of a credential a config hands a server, never the credential, and a test asserts it.
Governing them
Nothing here is a new enforcement path. All three reach the world through a shell, a binary and a socket, so they use the seams that already exist.
$memnox explain ruflo$memnox mcp wrap$memnox run -- npx ruflo swarmFederation
Ruflo and OpenClaw can both hand work to agents on other machines. When that is switched on, the scan says so, and says what it cannot do about it:
One of these works with agents on other machines; this scan sees only here.The far side is somebody else's laptop. A local scan that implied otherwise would be worse than one that admits the edge of what it knows.
In --json
memnox scan --json emits the capability inventory, version 2, which added
two arrays:
harnesses[]array
chains[]array
Version 1 could not express either without lying about the count: a harness is one agent row and several principals.



