--- title: Approvals and pre-tool gates description: Holding an agent action before the tool runs — how pre-tool hooks work per runtime, which are fail-closed, the HITL queue, and phone approvals. keywords: agent pre-tool hook, human in the loop agent, PreToolUse hook, agent approval gate, fail closed hook eyebrow: Guard & governance --- # Approvals and pre-tool gates Guard policies act *during* a run, after a detector has seen enough to be sure. A pre-tool gate acts *before* the tool runs, on a single action. Different timing, different guarantees, and worth understanding separately. ## How a gate works Where a runtime exposes a pre-tool hook — Claude Code's `PreToolUse` is the clearest example — ClawMetry can register with it. When the agent is about to call a gated tool, the hook fires, ClawMetry holds the action, and a request appears in the approval queue. The agent waits. You approve or reject. The decision goes back through the hook. ## Fail-closed matters The whole value of a gate is what happens when it *cannot answer* — the daemon is down, the hook times out, the socket is gone. - **Fail-closed**: the action does not proceed. The gate is a real control. - **Fail-open**: the action proceeds. The gate is a convenience, not a control. ClawMetry states which each runtime's hook is rather than implying a guarantee it cannot make. Where a hook is fail-open, treat the gate as advisory and put the real limit somewhere that cannot be bypassed — [the proxy](/docs/guard/proxy/), or the runtime's own permission system. :::warning Never delete a foreign hook Runtimes keep hooks in a shared configuration. ClawMetry marks the entries it owns and only ever removes its own. If you are editing hook configuration by hand, do the same — deleting an entry you did not create breaks somebody else's tooling, silently. ::: ## The HITL queue ```bash curl -s localhost:8900/api/hitl/pending | jq curl -s localhost:8900/api/hitl/status/ | jq curl -s localhost:8900/api/hitl/decide -X POST \ -H 'content-type: application/json' \ -d '{"request_id": "…", "decision": "approve"}' ``` An unanswered request stays pending. It does not time out into an approval — that would defeat the point — and the badge on the navigation keeps showing it. There is also a flag endpoint for marking a session as needing attention without blocking it: ```bash curl -s localhost:8900/api/hitl/flag -X POST \ -H 'content-type: application/json' -d '{"session_id": "…", "reason": "…"}' ``` ## Phone approvals With cloud sync connected, a pending approval can reach your phone as a push notification and be decided from the lock screen. The relay is a long poll rather than a fixed-interval push, so a decision reaches the waiting agent in seconds. This is what makes gating practical rather than annoying: a gate you can only clear from the machine is a gate you will turn off. ## What to gate Gating everything is the same as gating nothing — you will approve reflexively within a day. Gate the things where you would genuinely want to look: - Writes outside the project directory - Anything that touches credentials or key material - Network calls to hosts that are not on your allowlist - Destructive commands — recursive deletes, force pushes, migrations - Privilege escalation The tool-permission surface is where the "which tools, where" part is configured. → [Tool permissions](/docs/guard/tool-policy/) ## Approvals versus policies | | Pre-tool gate | Guard policy | |---|---|---| | Fires | Before one tool call | After a detector sees a pattern | | Decides | A human, synchronously | The policy, autonomously | | Blocks | That one action | Pauses, stops or kills the session | | Needs | A runtime hook | The three locks | | Good for | Known-dangerous actions | Agents that have gone off track | Use both. A gate stops the specific thing you knew to worry about; a policy stops the thing you did not. ## NeMo Guardrails On a NemoClaw node, the guardrails layer has its own approval queue for actions the policy held. It surfaces on the NemoClaw tab and through its own endpoints: ```bash curl -s localhost:8900/api/nemoclaw/pending-approvals | jq curl -s localhost:8900/api/nemoclaw/rules -X POST -d '{}' -H 'content-type: application/json' | jq ``` `nemo_governance` is a **free feature** and applies to any runtime. ## Tier The approval queue is Starter and above (`approval_queue`). The tool-policy surface and pre-tool gates are separate features.