---
title: Human-in-the-Loop (HITL)
description: How DefenseClaw escalates risky tool calls to a human operator. Covers when HITL fires, how min-severity gates the prompt, and the per-connector difference between native ask and downgraded confirm verdicts.
keywords:
  - DefenseClaw human in the loop
  - DefenseClaw HITL
  - human approval AI agent
  - native ask AI agent
  - downgraded confirm verdict
---

Human-in-the-Loop (HITL) sits between observe (log only) and full enforcement. When a finding clears the configured severity, the agent pauses and waits for an operator decision — approve, deny, or supply a reason.

<Callout type="info">
HITL is opt-in and only meaningful in **action mode**. It is mutually exclusive with observe mode; observe never blocks, so there is nothing to pause on.
</Callout>

## Two delivery models

<Cards>
  <Card title="Native ask" description="The connector exposes a hook event that can prompt the operator inside the agent UI. The agent pauses; the operator clicks approve/deny; the agent continues. No context switch." />
  <Card title="Downgraded confirm" description="The connector cannot natively prompt the operator, so DefenseClaw downgrades the verdict to confirm. The raw_action is preserved in the audit log and the operator approves via the DefenseClaw TUI / OpenClaw plugin instead." />
</Cards>

## Per-connector behaviour

| Connector | Model | Surface |
| --- | --- | --- |
| OpenClaw | Native ask + plugin | Plugin-mediated approval reaches the OpenClaw chat origin |
| Claude Code | Native ask | PreToolUse prompt inside Claude Code |
| Cursor | Native ask | beforeShellExecution + beforeMCPExecution prompts inside Cursor |
| GitHub Copilot CLI | Native ask | preToolUse prompt inside Copilot CLI |
| ZeptoClaw | Downgraded confirm | DefenseClaw TUI |
| Codex | Downgraded confirm | DefenseClaw TUI / OpenClaw plugin |
| Hermes | Downgraded confirm | DefenseClaw TUI |
| Gemini CLI | Downgraded confirm | DefenseClaw TUI |
| Windsurf | Downgraded confirm | DefenseClaw TUI |

For the full machine-readable view see the [Capability Matrix](/docs/capability-matrix).

## Configure

```bash
defenseclaw setup guardrail \
  --mode action \
  --human-approval \
  --hilt-min-severity high \
  --restart
```

<TypeTable
  type={{
    "--human-approval / --no-human-approval": {
      type: "flag",
      description: "Toggle HITL on or off. Action mode only.",
    },
    "--hilt-min-severity": {
      type: "high|medium|low|critical",
      description: "Lowest severity that triggers an approval prompt. CRITICAL findings always block regardless of HITL. Click accepts the value case-insensitively; the underlying config stores the canonical uppercase rank label.",
      default: "high",
    },
  }}
/>

## Decision flow

<Flow
  direction="TB"
  caption="HITL is the difference between block and pause. CRITICAL findings always block; HIGH findings pause if HITL is on, otherwise block; LOW/MEDIUM never pause unless you opt in via --hilt-min-severity."
>
  <Node id="req" kind="generic">Tool call / prompt</Node>
  <Node id="score" kind="policy">Score finding</Node>
  <Node id="crit" kind="decision">Severity</Node>
  <Node id="hitl" kind="decision">HITL on?</Node>
  <Node id="native" kind="decision">Native ask?</Node>
  <Node id="block" kind="generic">Block</Node>
  <Node id="allow" kind="generic">Allow</Node>
  <Node id="ask" kind="agent">Ask in agent UI</Node>
  <Node id="confirm" kind="operator">{`Downgrade to confirm\nin DefenseClaw TUI`}</Node>
  <Edge from="req" to="score" />
  <Edge from="score" to="crit" />
  <Edge from="crit" to="block" label="CRITICAL" />
  <Edge from="crit" to="hitl" label="HIGH" />
  <Edge from="crit" to="allow" label="MEDIUM/LOW" />
  <Edge from="hitl" to="block" label="no" />
  <Edge from="hitl" to="native" label="yes" />
  <Edge from="native" to="ask" label="yes" />
  <Edge from="native" to="confirm" label="no" />
  <Edge from="ask" to="allow" />
  <Edge from="confirm" to="allow" />
</Flow>

## Operator workflow

<Steps>

<Step>
The agent attempts a tool call. The PreToolUse / beforeShellExecution / fetch_request hook fires (whichever the connector exposes).
</Step>

<Step>
The hook reaches the gateway, which scores the action, finds a HIGH finding, and returns a `pause` verdict because HITL is on.
</Step>

<Step>
On native-ask connectors, the agent surfaces a prompt inside its UI. On downgraded-confirm connectors, the operator sees the pending action in `defenseclaw tui` (or the OpenClaw plugin queue).
</Step>

<Step>
The operator approves or denies. The decision is written to the audit log alongside the original finding.
</Step>

<Step>
The agent receives the decision and either runs the tool call or surfaces the deny reason to the user.
</Step>

</Steps>

## What HITL is not

<Callout type="warn">
HITL is not a replacement for a strong rule pack. CRITICAL findings should still block unconditionally — operators are slow, and CRITICAL exists for a reason. HITL is for the messy middle: actions that are usually fine but occasionally aren't.
</Callout>
