<!-- source: https://deepwiki.com/qhkm/zeptoclaw/6.7-loop-guards-and-circuit-breakers -->

# Loop Guards and Circuit Breakers

- .claude/settings.json
- .gitignore
- src/agent/compaction.rs
- src/agent/loop.rs
- src/channels/telegram.rs
- src/error.rs
- src/providers/error_classifier.rs
- src/providers/fallback.rs
- src/utils/sanitize.rs

## Purpose and Scope

This page documents ZeptoClaw's multi-layered loop detection and circuit breaking system, which prevents agents from falling into infinite loops during tool execution. The system tracks tool call patterns using SHA256 signatures, detects repeated identical calls and outcomes, identifies ping-pong oscillations, and applies graduated responses (warn → block → circuit break) to stop runaway executions.

The implementation resides primarily in `src/agent/loop_guard.rs` [src/agent/loop_guard.rs1-14](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L1-L14) and is integrated into the core execution loop in `src/agent/loop.rs` [src/agent/loop.rs129-225](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L129-L225)

## Architecture Overview

The loop guard system operates within the `AgentLoop`'s tool execution pipeline, intercepting tool calls before they execute and recording outcomes after completion.

**Loop Guard Architecture**

```

```

**Sources:** [src/agent/loop.rs129-172](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L129-L172) [src/agent/loop.rs177-225](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L177-L225) [src/agent/loop_guard.rs65-86](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L65-L86)

## Loop Detection Mechanisms

### Call Signature Tracking

Each tool call is hashed using SHA256 of `(tool_name, arguments_json)` to create a unique signature. The `LoopGuard` maintains a sequence of these signatures and counts how many times each signature appears.

**Call Signature Hash Computation**

```

```

The `ToolCallSig` struct at [src/agent/loop_guard.rs52-56](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L52-L56) is used to pass batch data into the guard. The `check` method at [src/agent/loop_guard.rs114-192](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L114-L192) performs the primary signature analysis.

**Sources:** [src/agent/loop_guard.rs52-56](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L52-L56) [src/agent/loop_guard.rs114-192](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L114-L192)

### Outcome-Based Detection

Beyond tracking call signatures, the loop guard also hashes tool **outcomes** (the first 1000 bytes of the result). This catches cases where the LLM repeatedly makes different calls that produce the same result (e.g., trying different search queries that all return "No results found").

**Outcome Tracking Flow**

```

```

The `check_loop_guard_outcomes()` function at [src/agent/loop.rs177-225](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L177-L225) processes results after tool execution. The `record_outcome` method at [src/agent/loop_guard.rs198-251](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L198-L251) manages the outcome state.

**Sources:** [src/agent/loop.rs177-225](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L177-L225) [src/agent/loop_guard.rs198-251](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L198-L251)

### Ping-Pong Pattern Detection

The loop guard detects **oscillations** where the LLM alternates between two or three tool calls repeatedly (e.g., A → B → A → B → A). This is tracked by looking for cycles of length 2 or 3 in the `call_sequence`.

The detection logic is encapsulated in `check_ping_pong` at [src/agent/loop_guard.rs253-305](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L253-L305) It checks for:

- Period-2 oscillations : [..., A, B, A, B] src/agent/loop_guard.rs 265-281
- Period-3 oscillations : [..., A, B, C, A, B, C] src/agent/loop_guard.rs 283-302

**Sources:** [src/agent/loop_guard.rs253-305](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L253-L305)

### Poll Command Relaxation

Some tools legitimately need to be called repeatedly (e.g., checking status, polling an API). The loop guard applies a **threshold multiplier** for tools matching poll/status patterns.

Commands matching patterns defined in `POLL_PATTERNS` (including `status`, `poll`, `wait`, `docker ps`, `kubectl get`, `git status`) have their `warn_threshold` and `block_threshold` multiplied by the `poll_multiplier` [src/agent/loop_guard.rs89-96](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L89-L96)

**Sources:** [src/agent/loop_guard.rs89-96](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L89-L96) [src/agent/loop_guard.rs139-145](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L139-L145)

## Graduated Response System

The loop guard uses a three-tier response system based on repetition counts defined in `LoopGuardAction` [src/agent/loop_guard.rs26-38](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L26-L38):

**Graduated Response Flow**

```

```

The `check_loop_guard()` function at [src/agent/loop.rs129-172](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L129-L172) handles these actions at the call site.

**Sources:** [src/agent/loop.rs141-171](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L141-L171) [src/agent/loop_guard.rs26-38](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L26-L38) [src/agent/loop_guard.rs153-189](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L153-L189)

## Circuit Breaker Mechanics

The **global circuit breaker** tracks the cumulative count of all repetitions across all tool call signatures within a single agent run. Once `total_repetitions >= global_circuit_breaker`, the `CircuitBreak` action is returned, stopping the agent immediately [src/agent/loop_guard.rs153-162](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L153-L162)

**Circuit Breaker Trigger Conditions**

```

```

**Sources:** [src/agent/loop_guard.rs153-162](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L153-L162) [src/agent/loop.rs161-170](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L161-L170)

## Configuration

Loop guard behavior is controlled via the `LoopGuardConfig` struct [src/agent/loop_guard.rs65-86](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L65-L86)

**Sources:** [src/agent/loop_guard.rs65-86](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L65-L86) [src/agent/loop_guard.rs139-145](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L139-L145)

## Memory Management and Window Pruning

To prevent unbounded memory growth during long agent runs, the loop guard implements a **sliding window** of recent calls. When the `call_sequence` exceeds `window_size`, the oldest entries are pruned [src/agent/loop_guard.rs311-325](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L311-L325)

The `prune_call_window` method at [src/agent/loop_guard.rs311-325](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L311-L325) performs this maintenance:

1. Removes oldest entries from call_sequence .
2. Rebuilds call_counts map from the remaining window to ensure counters reflect only recent history.

**Sources:** [src/agent/loop_guard.rs127-131](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L127-L131) [src/agent/loop_guard.rs311-325](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L311-L325)

## Summary

ZeptoClaw's loop guard system provides defense-in-depth against infinite loops through:

1. SHA256-based call signature tracking for detecting repeated identical calls src/agent/loop_guard.rs 114-126
2. Outcome hashing to catch different calls producing the same result src/agent/loop_guard.rs 198-251
3. Ping-pong oscillation detection for alternating patterns src/agent/loop_guard.rs 253-305
4. Poll command relaxation for legitimate repeated calls src/agent/loop_guard.rs 89-96
5. Graduated responses (warn → block → circuit break) src/agent/loop_guard.rs 26-38
6. Sliding window pruning to bound memory usage src/agent/loop_guard.rs 311-325

The system operates transparently within the tool execution pipeline, injecting informative system messages to help the LLM break out of loops while providing hard stops when repetition exceeds safe limits.

**Sources:** [src/agent/loop.rs129-225](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop.rs#L129-L225) [src/agent/loop_guard.rs1-14](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/agent/loop_guard.rs#L1-L14)
