Hermes Agent plugin / per cron job / built on Hermes by Nous Research
MANDATE.
A leash for the job nobody is watching.
watch → propose → a human approves → off-mandate calls blocked
toolsterminal 12x, read_file 3x
4 allowed
pathssrc 6x, src/** 3x, reports/*.md 3x
✕#2✕#3
3 allowed · 2 blocked
commandsgit status, git log, grep, ls
✕#1✕#4
4 allowed · 2 blocked
hostsnone observed
no host allowed
0 allowed
allowed, bar height is evidenceblocked call, drift idpending approvalnumbers from the demo capture, video/run_demo.cast
learned, not listed
1 job.
1 policy.
1 policy.
Compiled from the job’s own observed runs. Rivals ship one fixed pattern list for everyone.
human in the loop
0.
Rules enforced before a person runs hermes mandate approve.
where it bites
pre_
tool.
tool.
Vetoes the call in pre_tool_call, below anything a prompt injection can reach.
Quickstart
Install, observe, propose, approve, and enforce.
Proof
make prove on Hermes v0.23.0 and v0.23.1, 112 tests.Concepts
Mandate format, evidence counts, the Leash Line, drift, widen, undo, fail-closed.
Security and limits
What Mandate sees, what it does not, and the honest known limits.

Why this exists
Hermes users have asked for a way to restrict unattended cron jobs, and several open bugs show that Hermes’s owncron_mode: deny can be bypassed or ignored. These titles were verified against the live issues on 10 Nov 2026:
- #20984 (open): feat: add cron_mode: allowlist to restrict cron jobs to command_allowlist only. A feature request for a cron-only allowlist so a job cannot use the rest of the toolset.
- #60505 (open): Approval gate: fail-closed option for non-interactive contexts + permanent allowlist bypasses cron_mode deny. No fail-closed path for unattended runs, and a permanent allowlist can bypass
cron_mode: deny. - #144434 (open): [Bug]: command_allowlist (Always Allow) also exempts commands in cron runs with cron_mode: deny. “Always Allow” still applies during cron, even when cron mode is deny.
- #83626 (open): Cron command guards ignore cron_mode when HERMES_EXEC_ASK is inherited. Inherited ask settings can make the cron guards ignore the configured cron mode.
- #58673 (open): [Bug]: approvals.cron_mode: deny never applies to gateway-hosted cron/kanban sessions — each gated call blocks for approvals.gateway_timeout. Gateway-hosted cron and kanban sessions do not get deny; they wait out the gateway timeout instead.
approve from a cron run, so approvals.cron_mode cannot turn a violation into an approval.
How it is different
Rivals such as Hermes Guard and agent-security-guard use hand-written fixed pattern lists. Mandate learns a per-job policy from observed runs, then a human approves it. The three can run together. The other two look for injected content and risky transitions. Mandate limits a known job to the calls it was approved to make. The comparison table, with source links, is in the repository README.Why a plugin and not a prompt
- Enforcement happens in
pre_tool_call, before the tool runs. A prompt can be ignored or overwritten by a prompt injection in an issue body. A hook vetoes the call regardless of what the model wants. - It needs the identity of the running cron execution (
ctx.current_cron_execution()), so each job gets its own policy and two jobs running at once never share one. - It keeps state across runs (observations, versions, approvals, drift) in its own SQLite store.
- It parses arguments: shell segments, nested interpreters, resolved paths, parsed hostnames.
About the images
The yard photographs, including the one behind the hero on this page, are generated plates (ChatGPT), graded to one palette. The tags in the hero and the Leash Line strip above are HTML and CSS, built from the four blocked calls and rule counts in the deterministic demo capture (video/run_demo.cast). The Leash Line images are drawn by code from the deterministic demo capture (video/run_demo.cast) and are labeled as demo data. The Leash Line screenshot in Concepts and Proof is a real terminal capture from demo/run_demo.sh.