Observed since 20 Oct, 22:04 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
User-space runtime policy guard with deterministic control decisions and forensic evidence.
An autonomous agent process can spawn a child that reads ~/.ssh/id_rsa, writes outside its
workspace, or shells out to curl/wget -- and by default nothing watches for that at runtime
except the agent's own (possibly compromised or simply buggy) judgment. Sandboxes and
input-side filters don't cover this: they run before or around the agent, not against what its
process tree actually does once it starts executing. Agent Gorgon is the userspace layer that
watches the running process tree, applies a deterministic policy to what it sees, and can pause
or kill a matching process -- calibrated first in a mode that changes nothing.
See what an autonomous agent process does, apply deterministic runtime policy, and keep evidence of every control decision. Agent Gorgon observes the process tree plus file and network activity visible from user space. It can safely rehearse policy in audit-only mode, then attempt SIGSTOP or SIGKILL for reviewed triggers when active controls are enabled.
Version 0.1.8 made
agent_gorgonthe canonical Python import andagent-gorgonthe primary command. The earlieragent_wardenimport andagent-wardencommands remain available as deprecated compatibility aliases. Version 0.2.0 adds the packagedagent-gorgon-audit-democommand: a one-command, audit-only owned-process demo that works from a barepip install. Version 0.3.0 addsagent-gorgon run, which launches a command and watches the process tree it creates, and the packaged--scope coding-agentstarter scope.
agent-gorgon run wraps the command you already
use, and PID mode attaches to a process you did not launch. Neither requires the target
application to adopt an SDK.The packaged audit demo is the safe first run: it spawns three processes it owns (no real agent,
no network access, no credentials needed), watches them in --audit-only mode -- which never
sends SIGSTOP/SIGKILL -- and writes a machine-readable JSON receipt comparing the observed
verdict against a declared ground truth for each scenario.
pip install agent-gorgon==0.3.1
agent-gorgon-audit-demo --out /tmp/agent-gorgon-audit-demo.json
This is the real output from running that command (Python 3.13, macOS/Darwin, this environment):
{
"generated_at": "2026-09-18T08:24:43Z",
"false_trigger_or_miss_count": 1,
"scenarios": [
{"scenario": "safe_workspace_write", "expected_verdict": "SAFE", "observed_verdict": "SAFE", "match": true},
{"scenario": "suspicious_child_name", "expected_verdict": "HALT", "observed_verdict": "SAFE", "match": false},
{"scenario": "forbidden_extension_write", "expected_verdict": "KILL", "observed_verdict": "KILL", "match": true}
]
}
exit status: 1
agent-gorgon-audit-demo exits 0 only when every scenario's observed_verdict matches its
expected_verdict, and nonzero otherwise (false_trigger_or_miss_count says how many did not);
it never exits nonzero because a control action fired, since --audit-only never sends
SIGSTOP/SIGKILL. On this run the suspicious_child_name fixture wasn't attributed
("total_actions": 0) inside this sandboxed shell, most likely a process-visibility limit of
this execution environment, not a change made here -- see docs/EVIDENCE.md for a full
three-for-three receipt captured on macOS ARM outside a sandbox. Either way, no file was modified
and no process was paused or killed: that's what "audit-only" means, and it held regardless of
the verdict match. Read the receipt at the --out path before treating any run as a passing
calibration.
Once you've seen the demo's audit-only behavior, wrap a real workload with agent-gorgon run
(same audit-only guarantee, no signals sent unless you add --enforce):
agent-gorgon --version
agent-gorgon run --audit-only --scope coding-agent -- <your agent command>
The version readback confirms the installed command before it observes a workload. CI exercises
Python 3.9–3.12 on Ubuntu. Production use on macOS, Windows, or Python 3.13+ is currently
UNEVALUATED; active controls and command reduction are POSIX-oriented.
Agent Gorgon launches your command, watches the process tree it creates, and prints what it would have halted -- without pausing or terminating anything. When the command exits you get its exit status back plus one summary line:
agent-gorgon run: mode=audit-only exit=0 observed=14 safe=11 flags=3 would-halt=0 would-kill=0 evidence=/home/you/.local/share/agent-gorgon/logs/actions_20260911_101500.jsonl
Read that evidence file before you turn anything on. Active SIGSTOP/SIGKILL controls require an
explicit --enforce, and they are worth enabling only once the flags you see are the ones you
expect. Watch a command you launch covers the details;
attaching to an already-running process is
the advanced path.
The package, Python import, and primary command all use Gorgon names:
agent-gorgon --help
agent-gorgon run --help
For Python integrations, import the canonical namespace:
from agent_gorgon.warden import Scope
Existing agent_warden imports and agent-warden / agent-warden-forensic commands continue to
work as deprecated compatibility aliases. The legacy commands print a deprecation notice;
update integrations to the Gorgon names when convenient.
The shim's source and its deprecation window live in
compat/suy-sideguy/README.md.
Requires Python 3.9+. Start with --audit-only; active controls are enabled only when that flag is
omitted, after you have reviewed the policy against a disposable target.
agent-gorgon run removes the "find the PID first" step: it launches the command itself, watches
the process tree that command creates, forwards the command's exit status, and writes the same
evidence JSONL as PID mode.
agent-gorgon run --audit-only --scope coding-agent -- python3 my_agent.py
agent-gorgon run --audit-only --scope coding-agent -- npm test
--scope coding-agent is a starter scope shipped inside the wheel, written for a coding agent
(Claude Code, Codex, Aider, or your own harness). It allows the directory you launched from plus
the toolchain caches and read-only system paths every build touches, so ordinary work stays quiet;
it treats reads of ~/.ssh, ~/.aws, ~/.gnupg, ~/.config/gcloud, ~/.config/gh, ~/.netrc,
~/.git-credentials and key material (.pem, .key, .p12) as KILL verdicts, and curl,
wget, nc and the other transfer tools as forbidden commands. Anything outside the allowed
trees -- an out-of-tree .env, a connection to a host that is not on the allowlist -- is FLAGged
rather than silently accepted. --scope starter remains the narrower low-disruption profile.
Calibrate before you enforce. The packaged scope cannot know where your code lives beyond the launch directory, so run a real session in audit-only, read the evidence, and copy the file to add your own trees:
cp "$(python3 -c 'from agent_gorgon.warden import resolve_scope_path; print(resolve_scope_path("coding-agent"))')" .
agent-gorgon run --audit-only --scope ./coding-agent.yaml -- python3 my_agent.py
It is audit-only by default -- verdicts are recorded and no SIGSTOP or SIGKILL is sent unless
you pass --enforce. The last line is a one-line session summary on stderr, so the watched
command keeps stdout to itself:
agent-gorgon run: mode=audit-only exit=0 observed=14 safe=11 flags=3 would-halt=0 would-kill=0 \
evidence=/home/you/.local/share/agent-gorgon/logs/actions_20260911_101500.jsonl
Useful options: --out FILE writes the action evidence JSONL to an explicit path,
--scope FILE selects a scope, --poll sets the poll interval, --enforce turns on active
controls, and --shutdown-grace bounds how long a relayed signal is given.
Behavior worth knowing before you wrap a real session:
agent-gorgon run is relayed to the command's group, always
preceded by SIGCONT, so a paused tree is never left stopped.128+N.agent-gorgon run (for example your own > session.log
redirect) is not attributed to the command. A file the command opens itself still is.To attach to a process you did not launch, see Advanced: attach to an already-running process.
agent-gorgon run covers the common case. PID mode is for attaching to a process you did not
launch -- a long-lived agent daemon, a session someone else started, a process inside a supervisor.
It takes an exact --agent-pid and is otherwise identical: the same scopes, the same verdicts, the
same evidence.
This POSIX demo creates a temporary command named wget that only runs sleep. Agent Gorgon sees
the suspicious child name and records the HALT it would request, but --audit-only sends no signal
and the command performs no network activity:
DEMO_DIR=$(mktemp -d /tmp/agent-gorgon-demo.XXXXXX)
ln -s "$(command -v sleep)" "$DEMO_DIR/wget"
/bin/sh -c '"$1" 3 & wait' agent-demo "$DEMO_DIR/wget" &
TARGET_PID=$!
agent-gorgon \
--scope starter \
--agent-pid "$TARGET_PID" \
--poll 0.05 \
--no-llm \
--audit-only \
--log-dir "$DEMO_DIR/evidence"
The useful result is explicit:
Control: audit-only (SIGSTOP/SIGKILL disabled)
LLM: qwen3:4b disabled (rules only)
🟡 AUDIT ONLY, would HALT: Suspicious process spawned: wget
Observed: 1 | Safe: 0 | Flags: 0 | Halts: 1 | Kills: 0
Generate a private JSON summary at an explicit path:
agent-gorgon-forensic \
--last-hours 24 \
--workspace "$DEMO_DIR/workspace" \
--evidence-dir "$DEMO_DIR/evidence" \
--out "$DEMO_DIR/report.json"
The installed starter scope is for audit-only evaluation. For a real workload, copy and narrow a
scope from examples, prefer an exact --agent-pid, and keep evidence outside the
target's workspace. Remove the temporary demo directory when you no longer need its report.
For a fully scripted version of this demo -- three scenarios (SAFE/HALT/KILL), each run against a process the command spawns and owns, diffed against a declared ground truth -- run:
agent-gorgon-audit-demo --out /tmp/agent-gorgon-audit-demo.json
This works from a bare pip install agent-gorgon, no repository checkout required. It prints a
machine-readable JSON receipt with each scenario's expected vs. observed verdict, attribution
counts, and honest watcher-overhead measurements, and exits nonzero if any scenario's observed
verdict does not match its declared ground truth. See docs/EVIDENCE.md for a sample result and
docs/HARNESS_RECIPES.md for how to add your own scenario.
agent-gorgon run --audit-only --scope coding-agent -- <command> launches a command you own,
watches the tree it creates, and writes action JSONL plus a one-line summary. It is the
audit-only path for a real workload.agent-gorgon --scope starter --agent-pid <pid> --audit-only --no-llm attaches to one exact
process that is already running. It is not a process-name search and does not launch a command.agent-gorgon-audit-demo --out RECEIPT.json runs the packaged, owned SAFE/HALT/KILL fixtures in
audit-only mode. It is the reproducible receipt path, not evidence about your own workload.After the audit demo exits zero, read the receipt before treating it as a usable calibration:
agent-gorgon-audit-demo --out /tmp/gorgon_evidence.json
python3 - /tmp/gorgon_evidence.json <<'PY'
import json
import sys
with open(sys.argv[1], encoding="utf-8") as handle:
receipt = json.load(handle)
required = {"generated_at", "scenarios", "false_trigger_or_miss_count", "overhead"}
assert required <= receipt.keys()
assert receipt["false_trigger_or_miss_count"] == 0
assert receipt["scenarios"]
for scenario in receipt["scenarios"]:
assert {"expected_verdict", "observed_verdict", "match", "observation_complete"} <= scenario.keys()
assert scenario["match"] and scenario["observation_complete"]
print(f"receipt verified: {len(receipt['scenarios'])} owned audit-only scenarios")
PY
This establishes that the built-in fixtures matched their declared ground truth with at least one attributed observation per scenario. It does not establish that a policy covers a different workload, OS, process tree, or poll interval.
Use Agent Gorgon when you run autonomous or semi-autonomous agents and need userspace runtime observation, reactive process controls, and forensic evidence as one layer in a defense-in-depth setup.
If 40 files disappear between snapshots, agent-gorgon records 40 unattributed delete observations. It does not suspend the monitored process from those observations alone because a directory diff cannot establish which process performed the deletion.
SIGKILL for deterministic severe violationspsutil.open_files() is best-effort and OS-dependentDefault paths:
~/.local/share/agent-gorgon/warden.log~/.local/share/agent-gorgon/logs/actions_*.jsonl~/.local/share/agent-gorgon/logs/incidents/*.jsonAgent Gorgon creates these directories for the current user only (0700) and evidence files as
private (0600). Define retention and rotation appropriate to your environment.
--no-llm, it makes a loopback HTTP probe to
http://localhost:11434 to check for Ollama. Only when the configured model is available does
it send the current action, a scope summary, and up to 20 recent actions to that local Ollama
service for non-enforcing advisory analysis. --no-llm disables both the loopback probe and
those advisory calls.Start with agent-gorgon run --audit-only and a reviewed scope, against a workload you can afford
to lose. Add --no-llm for a deterministic no-advisory trial. Audit-only records verdicts but sends no SIGSTOP
or SIGKILL. Enable active controls (omit --audit-only in PID mode, or pass --enforce to
agent-gorgon run) only after validating the policy and OS visibility for the exact workload;
there is no interactive confirmation mode once active controls are enabled.
SIGKILL is immediate and can interrupt legitimate work if policy is too broad.agent-gorgon run, which
watches exactly the process it launched, or an exact --agent-pid.| Verdict | Meaning | Response |
|---|---|---|
SAFE | Action is within policy | Continue |
FLAG | Suspicious, below threshold | Log, continue |
HALT | Dangerous pattern detected | Attempt process-tree SIGSTOP (reversible); write local evidence |
KILL | Critical violation | Attempt process-tree SIGKILL; write local evidence |
FILE_DELETE events in 10 seconds — available to integrations that can supply attribution; built-in snapshot diffs do not activate this triggersh/bash wrapper is allowed; conventional relative project cleanup
remains low-noise when its observed cwd resolves inside filesystem.allowed_paths`...` and $(...) forms pause reversibly; single-quoted substitution text remains dataid_rsa or id_ed25519, plus key extensions such as *.pem or *.key under ~/.ssh; broad
directory rules belong in the operator's scope~/.openclaw/openclaw.jsonrm -rf command targeting a protected root — filesystem root, home, or a
configured forbidden root; relative operands are resolved against the observed child cwd, and
supported env wrappers plus root/home glob and ancestor forms are reduced before classification;
direct child argv is preserved so literal ~, $HOME, and wildcard bytes are not re-expandedfilesystem.forbidden_paths or extensions in filesystem.forbidden_extensionsEarly flag noise is normal during policy calibration on real workloads.
FLAG events as calibration data, not immediate defects.WARDEN_KILL_ON_FLAGS=1 explicitly enables accumulation kills using flag_threshold and flag_window.--audit-only.Current status based on repository checks and CI configuration; not a formal security certification.
pytest)python -m build).github/workflows/ci.yml)SECURITY.md)If agent-gorgon saves you time, please star the repo — it helps others find it.
Hermes Labs is an AI reliability engineering studio for production agents and LLM applications. agent-gorgon is the runtime-observation and control layer in its open-source toolkit. More at hermes-labs.ai.
pip install -e .[dev]
pytest
Also see:
CONTRIBUTING.mdSECURITY.mdPUBLISH_CHECKLIST.mdAGENTS.mdCODE_OF_CONDUCT.mddocs/AUDIT_CHECKLIST.mddocs/HARNESS_RECIPES.mdagent-gorgon-audit-demo (packaged), examples/harness/ (source-checkout wrapper), and
docs/EVIDENCE.mddocs/IMPLEMENTATION_PLAN_LAYERED.mdDownload counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.3.1 | 20 Sept 2026 | 8 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 22:04 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:f43a9d9e3bffa278d936770438251d3f6d5bc60957e7ef297a87adf6221a747f