Integration Guide

Hermes

Connect Hermes to DashClaw and get your first governed action into /decisions in under 20 minutes.

Instance URL detected: https://your-dashclaw-instance.example.com

1

Deploy DashClaw

Get a running instance. Click the Vercel deploy button or run locally.

Already have an instance? Skip to Step 2.

2

Install the Hermes plugin

One script symlinks the plugin into ~/.hermes/, appends the eight DashClaw hook entries to ~/.hermes/config.yaml (idempotent — sentinel markers prevent duplication on re-run), substitutes ${DASHCLAW_REPO} for the absolute repo path, and prints an env-var checklist. Re-run after every git pull to upgrade.

Terminal

# macOS / Linux
bash scripts/install-hermes-plugin.sh

# Windows
powershell -File scripts/install-hermes-plugin.ps1

# Sanity check
hermes dashclaw doctor

The doctor command runs a 4-section check: env vars, all 8 hooks on disk, plugin skills present, API reachability, and a finalize: true probe of /api/code-sessions/ingest-live.

3

Set environment variables

The hooks read these from the shell or a .env file in the project root. DASHCLAW_GUARD_UNAVAILABLE_POLICY defaults to block (fail closed). Set it to warn for development if you want stderr warnings instead of blocks when the guard is down.

.env

DASHCLAW_BASE_URL=https://your-dashclaw-instance.example.com
DASHCLAW_API_KEY=oc_live_...
DASHCLAW_AGENT_ID=hermes
DASHCLAW_HOOK_MODE=enforce
DASHCLAW_GUARD_UNAVAILABLE_POLICY=block
DASHCLAW_GUARD_TIMEOUT=5
4

Accept the hooks

Hermes prompts on first invocation of each (event, command) pair so you can review the eight commands before they fire. Accept once per hook, or set hooks_auto_accept: true in ~/.hermes/config.yaml after you have reviewed them. Trusted hooks persist across sessions.

In Hermes

# First Hermes session after install will prompt 8 times — once per hook.
# Each prompt shows the absolute command + matcher.

# Or non-interactive — set in ~/.hermes/config.yaml:
hooks_auto_accept: true

One-time per hook. The acceptance is keyed on the command string, so re-running install with the same DASHCLAW_REPO path keeps consent state intact.

5

Verify the managed block

Skim the managed block the install script wrote to ~/.hermes/config.yaml. Anything outside the start/end markers is your own content and was preserved verbatim. A .dashclaw-bak sibling holds the pre-install state.

~/.hermes/config.yaml

# >>> dashclaw start — managed block, do not edit by hand
#
# Re-run scripts/install-hermes-plugin.sh to refresh this block.

hooks:
  pre_tool_call:
    - matcher: "^(Bash|Edit|Write|MultiEdit|terminal|str_replace_editor|create_file)$"
      command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_pretool_hermes.py"
      timeout: 60

  post_tool_call:
    - matcher: "^(Bash|Edit|Write|MultiEdit|terminal|str_replace_editor|create_file)$"
      command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_posttool_hermes.py"
      timeout: 30

  pre_llm_call:
    - command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_pre_llm_hermes.py"
      timeout: 5

  post_llm_call:
    - command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_postllm_hermes.py"
      timeout: 15

  on_session_start:
    - command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_on_session_start_hermes.py"
      timeout: 10

  on_session_end:
    - command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_on_session_end_hermes.py"
      timeout: 15

  transform_tool_result:
    - command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_transform_tool_result_hermes.py"
      timeout: 5

  subagent_stop:
    - command: "python ${DASHCLAW_REPO}/.hermes/hooks/dashclaw_subagent_stop_hermes.py"
      timeout: 10

hooks_auto_accept: false
# <<< dashclaw end
6

Connect Discord (2 minutes)

A Discord bot turns your phone into a one-tap approval surface for risky tool calls. The built-in Discord adapter posts a DM with Approve / Deny buttons when a policy requires human judgment. Same setup as the Claude Code and Codex paths; ENV-only.

.env.local (or Vercel env vars)

DISCORD_BOT_TOKEN=<token>
DISCORD_PUBLIC_KEY=<64-char-hex>
DISCORD_APPROVER_USER_ID=<numeric-user-id>
DISCORD_APPROVER_ORG_ID=<your-org-id>
# Kill switch — leave unset or set to true to enable DMs
# DASHCLAW_ALERTS_DISCORD=false

Step-by-step Discord Developer Portal walkthrough is printed below.

7

Run Hermes and trigger a tool call

Ask Hermes to do anything that uses Bash, terminal, str_replace_editor, Edit, Write, or MultiEdit. The pre_tool_call hook fires automatically. For policies that require approval, your phone DMs you and Hermes pauses on the dashclaw_wait_for_approval MCP tool until you resolve.

Example prompt

Create a file called hello.txt with the contents "Hello from a governed agent"

Watch the terminal — you should see [DashClaw] messages as each hook evaluates the action. The pre_llm_call hook also injects pending approvals and active policies into every turn.

8

See the result in DashClaw

Open your DashClaw dashboard to confirm the action was recorded under the hermes agent id and that the live-ingest session shows turn-by-turn token counts.

Go to /decisions — you should see your tool call with agent_id 'hermes'. Go to /code-sessions — the live session shows per-turn message counts, populated by post_llm_call as the session runs.

What success looks like

Go to /decisions — you should see your Hermes tool call with agent_id 'hermes'. Go to /code-sessions — the live session shows per-turn token counts and tool calls as they happen.

Navigate to /decisions in your DashClaw instance. Your action should appear in the ledger within seconds of the agent run.

Governance as Code

Drop a guardrails.yml in your project root to enforce policies without code changes. DashClaw evaluates these rules at the guard step before any action executes.

guardrails.yml

version: 1
project: my-hermes-project
description: >
  Governance policy for Hermes Agent tool calls.
  Blocks destructive shell commands. Warns on deployment.

policies:
  - id: block_destructive_shell
    description: Block rm -rf and database drops
    applies_to:
      tools:
        - Bash
        - terminal
        - str_replace_editor
    rule:
      block: true
    when:
      command_contains:
        - "rm -rf"
        - "drop table"

  - id: warn_on_deploy
    description: Require approval for deployment commands
    applies_to:
      tools:
        - Bash
        - terminal
    rule:
      require: approval
    when:
      command_contains:
        - "git push"
        - "vercel deploy"

Hermes-specific notes

## Hermes-specific notes

### Hook surface (8 events vs Codex's 3)
Hermes exposes a richer lifecycle than Claude Code or Codex. Beyond
pre/post_tool_call and on_session_{start,end}, DashClaw also wires:

- pre_llm_call  — every turn injects active policies + pending approvals
                  + today's action count via Hermes's context-injection
                  contract (5-minute cached)
- post_llm_call — per-turn live ingest to /api/code-sessions/ingest-live
- transform_tool_result — redacts 10 secret-pattern families (Anthropic /
                  OpenAI / AWS / GitHub / Slack / Stripe / JWT / PEM /
                  DashClaw keys) before the model sees tool output
- subagent_stop — records every delegate_task child exit as a DashClaw
                  action with action_type=subagent for the subagent-ROI
                  dashboard

### Live session ingest
post_llm_call pushes turn structure (model, usage, tool calls, assistant
preview, timestamp) to /api/code-sessions/ingest-live every turn. On
session close, on_session_end fires the finalize: true variant which
runs the optimizer + alerts pass on the completed session. Turn-level
attribution is visible immediately in /code-sessions — no waiting for a
Stop hook to flush.

### Secret redaction
transform_tool_result runs every tool output through the same redaction
patterns DashClaw uses in incident reports — Anthropic / OpenAI / AWS /
GitHub / Slack / Stripe API keys, JWTs, PEM private-key blocks, and
DashClaw keys themselves. Never blocks; just substitutes. CodeQL flags
the sys.stdout.write here as clear-text logging because it does not model
the redactor as a sanitizer — confirmed false positive.

### Backing out
Delete the managed block between the # >>> dashclaw start / # <<<
dashclaw end markers in ~/.hermes/config.yaml. A .dashclaw-bak file is
left next to the config on first install for full restore.

Discord setup

## Discord Developer Portal walkthrough

### Create the bot
- Open https://discord.com/developers/applications -> New Application
- Name the app; skip the Installation tab
- Open the "Bot" tab -> Reset Token -> copy as DISCORD_BOT_TOKEN
- Open "General Information" -> copy the Public Key as DISCORD_PUBLIC_KEY
- Under "Privileged Gateway Intents" leave ALL off (button-only bot)

### Invite the bot to a mutual server (so DMs work)
- Open "OAuth2" -> URL Generator -> scopes: "bot" -> permissions: "Send Messages"
- Paste the URL in a browser, invite the bot to a personal test server
- In Discord client, enable Developer Mode (Settings -> Advanced)
- Right-click your own user in the member list -> Copy User ID
- Paste as DISCORD_APPROVER_USER_ID

### Register the interactions endpoint
- In "General Information" set:
  Interactions Endpoint URL: https://<your-deployment>/api/discord/interactions
- Discord sends a PING; DashClaw responds {type:1} and the URL saves.

### Verify
- Trigger a Hermes tool call that hits an approval-required policy
- Your phone's Discord app lights up; tap Approve or Deny
- The DM edits in place to show APPROVED or DENIED with timestamp