HermesGate
HermesGate turns “run the checks again” into a bounded completion ceremony. It runs the repository's own commands, records exactly which content and tool versions were checked, and reuses a PASS only while those bytes still match.
It has no daemon and no runtime dependencies beyond Python 3.11+ and Git. Lifecycle hooks inspect receipts; they do not repair code, invoke a model, or authorize a push, pull request, or release.
Used this way, it is a deterministic quality gate for AI-generated pull requests: the same commit passes or fails the same declared checks the same way every time, so a coding agent's own changes get a repeatable, receipt-bound result before a human reviews the PR — not a merge decision or a correctness proof (see What PASS means).
Five-minute quickstart
Install the published package, then enter the repository you want to gate:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install hermes-gate
cd /path/to/your/git-repository
hermes-gate init
hermes-gate fast
hermes-gate full
hermes-gate doctor
For HermesGate development, run python -m pip install . from a local checkout
instead. Release builds verify the tag, package and runner versions, tracked
runner, distribution metadata, and packaged source bytes before upload; they also reject versions
superseded on PyPI after environment approval.
Time-limited distribution exception
The v0.1.6 release carries one direct, twelve-hour exception record for its Hermes Registry submission. It can be inspected locally with:
python scripts/verify_release.py --tag v0.1.6 \
--distribution-exception release/distribution-exceptions/v0.1.6-hermes-registry.json
The command expires automatically at the recorded UTC time. It is not used by the publish workflow and never bypasses the normal source, runner, tag, package, or artifact identity checks.
init detects repository-native Python or JavaScript commands and writes a
reviewable .hermes/gate.toml, a checksum-bound stdlib runner, and a CI
workflow. Existing integration files are not overwritten unless
hermes-gate init --force is explicit.
The copied runner also requires Python 3.11 or newer, even when the project it checks supports older Python versions. Run Gate under a supported interpreter; profile commands may select the project's own interpreter separately.
New default whitespace checks inspect selected working-tree, staged and untracked files using Git's whitespace rules. Existing profiles are preserved; adopting the new check in an existing repository requires a reviewed runner/profile update. The copied runner drains stdout and stderr concurrently while retaining at most 32 KiB of each stream; its truncation flag reports any discarded output.
Completion workflows
| Workflow | Use it for | Receipt boundary |
|---|---|---|
hermes-gate fast |
Short feedback over current changed paths | Exact content digest, selected paths, checks, elapsed time, and command versions |
hermes-gate review |
One bounded semantic review after fast passes | Exact digest, provider version, normalized findings, and suppression count |
hermes-gate full |
Complete repository-local test contract | Exact digest, full checks, elapsed time, and command versions |
A typical local ceremony is:
hermes-gate fast
hermes-gate review
hermes-gate full
hermes-gate boundary commit
The boundary command verifies configured receipts. Repositories that have never
been adopted (no profile and no Gate install manifest) are outside this rail and
pass the boundary unchanged; do not run init merely to satisfy a global hook.
An adopted repository with a missing profile remains fail-closed until its
profile is restored or uninstall-repo completes. The boundary never performs
the Git operation or grants owner authorization.
CLI
hermes-gate init [--force]
hermes-gate fast
hermes-gate repair
hermes-gate review
hermes-gate full
hermes-gate boundary commit|push|pr-create|pr-ready
hermes-gate doctor
hermes-gate uninstall-repo
hermes-gate delegate-judge
hermes-gate --version
Commands emit JSON with one terminal state: PASS, FAIL,
NOT_APPLICABLE, NOT_CONFIGURED, REVIEW_UNAVAILABLE, PARKED, or
ERROR.
Repository-native default
The generated profile uses argv arrays and the repository's existing Ruff,
pytest, npm, lint, typecheck, test, or build commands. It never installs these
tools. Runtime receipts, baselines, install manifests, and adapter artifacts live
under .git/hermes-gate/; generated tracked source contains no machine-specific
absolute paths.
[gate]
fast_budget_seconds = 8.0
full_required_local = false
[[fast]]
name = "ruff"
argv = ["ruff", "check", "{files}"]
timeout_seconds = 6.0
globs = ["**/*.py"]
{files} expands to separate argv entries. Shell strings are rejected.
Optional primitive adapters
HermesGate packages a standard-library loader and validator for the shared
gate-result/v1 schema. PyGate and QuickGate.js adapters are opt-in and
isolated; HermesGate never downloads or installs them.
PyGate 0.2.0 or newer:
[adapter]
enabled = true
name = "pygate"
argv = ["pygate"]
minimum_version = "0.2.0"
QuickGate.js 0.2.3 or newer:
[adapter]
enabled = true
name = "quick-gate"
argv = ["quick-gate"]
minimum_version = "0.2.3"
Adapter output is written below .git/hermes-gate/adapters/, validated against
the packaged contract, and then normalized into a HermesGate receipt. An absent,
old, or invalid primitive returns ERROR; it never falls through to an
unreviewed installation.
Review and hooks
review requires an exact fast PASS. CodeRabbit agent-mode JSONL is the initial
provider boundary. If it is unavailable, a clean committed diff may use an
installed hermes-pr-review fallback. Unparseable, unauthenticated, timed-out,
or unavailable review output is never relabeled PASS.
review.provider names that output contract and must be coderabbit;
review.argv[0] names the executable and may differ (for example a wrapper or
the cr alias). Any other provider name is a profile error: fast, review,
full, repair, and boundary all return ERROR with
invalid profile: review.provider …, and doctor reports profile.status: ERROR, because a command the engine cannot bind to the diff or parse can only
ever produce an unavailable or wrong review. doctor probes the executable the
profile names, resolved the same way review launches it.
install-codex and uninstall-codex are intentionally hidden integration
commands. Codex integration preserves unrelated hook and instruction content.
Claude settings and instruction surfaces remain outside Codex's ownership.
Claude Code plugin
The repository ships a self-contained Claude Code plugin at
claude-plugin/ — it bundles its own copy of
src/hermes_gate so a marketplace install works with no separate pip install. It wires three lifecycle hooks to the same hermes-gate hook
event handlers used by the manual Claude integration above:
| Event | Hook | Behavior |
|---|---|---|
SessionStart |
session-start |
Injects the compact completion contract as additional context. Always continues. |
Stop |
stop |
Runs the cached fast gate against session-changed code paths and reports a non-PASS reason as an advisory systemMessage. Never blocks. |
PreToolUse (matcher Bash) |
pre-tool-use |
Denies a detected commit/push/PR boundary command that is missing its matching receipt in an adopted repository; never-adopted repositories stay outside the rail. |
Every path fails open: a malformed payload, an unrecognized event, or an
internal error returns {"continue": true} rather than blocking the
session. Install it from this marketplace:
/plugin marketplace add hermes-labs-ai/claude-plugins
/plugin install hermes-gate@hermes-labs
tests/test_claude_plugin.py verifies the bundled claude-plugin/src
runtime is byte-identical to src/hermes_gate and exercises the hook
script as a subprocess with no hermes-gate package installed, so the
marketplace artifact is tested the same way Claude Code runs it.
Hermes Agent quality-gate seam
hermes-gate delegate-judge is a hidden integration command for one specific
seam: NousResearch's Hermes Agent quality gate, which spawns an argv-only
judge command per subagent task and sends one JSON object on stdin:
{"version": 1, "goal": "...", "summary": "...", "attempt": 1, "max_retries": 2,
"previous_feedback": ["..."], "task_index": 0, "subagent_id": "..." | null,
"session_id": null, "model": null, "api_calls": null, "completed": true,
"workspace": "/absolute/path/to/the/child/workspace" | null,
"workspace_isolated": true}
and reads exactly one JSON object from stdout:
{"verdict": "pass" | "retry" | "reject" | "error", "feedback": "..."}
Configure Hermes Agent's quality gate with:
hermes-gate delegate-judge
The command validates the request, then runs fast against workspace's own
Git repository root using the same internal engine hermes-gate fast uses —
no shell, no API-backed review, and no process-wide working-directory change,
so concurrent judge processes for different workspaces cannot race. A Gate
PASS or NOT_APPLICABLE maps to verdict pass. attempt is one-based (the
first attempt is 1) and max_retries counts the allowed correction turns
after that first attempt, so a material FAIL maps to retry while
attempt <= max_retries, and reject once that budget is exhausted — a
max_retries: 1 profile still retries the first (attempt: 1) failure.
previous_feedback may be a string, an array of strings, or null; the judge
never reads it. subagent_id and workspace may be null. workspace_isolated
is validated as a boolean when present. A null or absent workspace cannot be
judged and returns the fixed verdict error with feedback
workspace unavailable: request has no workspace path; an unusable path
returns workspace unavailable: path is not a directory. Neither echoes the
request. An invalid request, a missing .hermes/gate.toml profile, an
unavailable tool or adapter, or an internal error all map to error.
Feedback is a short, deterministic summary of the failing check names and
reasons; it never includes raw command stdout/stderr, full diffs, or source
content.
What PASS means
A PASS proves only that the declared commands passed for the receipt-bound local content. It does not prove universal correctness, security, mergeability, public release, adoption, or permission to push, publish, or create a pull request.
See SECURITY.md, CONTRIBUTING.md, and CHANGELOG.md for project policy and release history.
Metadata
Release files for hermes-gate 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hermes_gate-0.1.6.tar.gz | 79.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hermes_gate-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 137.8 kB
Release files / hermes_gate-0.1.6.tar.gz
| Download URL | hermes_gate-0.1.6.tar.gz |
|---|---|
| Size | 79.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1fabf63f1f014611bd368ace4164f5cc2af7778661e42fb970816e4ccbcc453
|
|
BLAKE2b-256 checksum How to use checksums |
1c27beaa95aab752529fc31d5c156f9b38c40285fa7d89fa2d71c7b888b26984
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency logRelease files / hermes_gate-0.1.6-py3-none-any.whl
| Download URL | hermes_gate-0.1.6-py3-none-any.whl |
|---|---|
| Size | 58.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
817d67faba6aa3ec1372148479649fc6f2bd57257e573c60d5cb51fec04206ae
|
|
BLAKE2b-256 checksum How to use checksums |
551cf32a064a467bab0eb6738921abad1d83b455733f6cbc2094db87559c0fce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency log