Circuit Breaker
The CircuitBreaker class detects stagnation in the autonomous loop and halts execution when progress stops.
States
┌──────────┐ no progress (3x) ┌────────────┐
│ │ ───────────────────────→ │ │
│ CLOSED │ │ HALF_OPEN │
│ │ ←─────────────────────── │ │
└──────────┘ progress resumes └────────────┘
│ │
│ same error (5x) still stuck
│ │
▼ ▼
┌──────────────────────────────────────────────────┐
│ OPEN │
│ (loop terminated) │
└──────────────────────────────────────────────────┘| State | Meaning | Loop Action |
|---|---|---|
CLOSED | Normal operation | Continue iterating |
HALF_OPEN | Stagnation detected | One more chance — monitor closely |
OPEN | Confirmed stagnation | Terminate loop immediately |
Thresholds
interface CircuitBreakerConfig {
noProgressThreshold: number // default: 3
sameErrorThreshold: number // default: 5
outputDeclineThreshold: number // default: 70 (percentage)
}| Threshold | Default | Trigger |
|---|---|---|
noProgressThreshold | 3 | Consecutive iterations with no measurable progress |
sameErrorThreshold | 5 | Same error message repeated across iterations |
outputDeclineThreshold | 70% | Output quality drops below 70% of baseline |
Interface
interface CircuitBreaker {
state: 'CLOSED' | 'HALF_OPEN' | 'OPEN'
recordProgress(metrics: IterationMetrics): void
recordError(error: string): void
check(): CircuitBreakerDecision
reset(): void
getStatus(): CircuitBreakerStatus
}
interface IterationMetrics {
filesChanged: number
testsPassing: number
outputLength: number
timestamp: Date
}
interface CircuitBreakerDecision {
allowContinue: boolean
state: CircuitBreaker['state']
reason: string | null
}
interface CircuitBreakerStatus {
state: CircuitBreaker['state']
consecutiveNoProgress: number
errorCounts: Record<string, number>
outputTrend: number[]
lastProgress: Date | null
}State Transitions
CLOSED → HALF_OPEN
Triggered when consecutiveNoProgress reaches noProgressThreshold. The circuit enters a watchful state — one more iteration without progress will open it.
HALF_OPEN → CLOSED
If the next iteration shows measurable progress (files changed, tests passing, output quality improves), the circuit resets to CLOSED. The counter resets.
HALF_OPEN → OPEN
If the watchful iteration also shows no progress, or the same error repeats sameErrorThreshold times, the circuit opens and terminates the loop.
CLOSED → OPEN
Direct transition if the same error occurs sameErrorThreshold consecutive times, bypassing HALF_OPEN entirely.
Once the circuit is OPEN, the loop cannot continue. The coordinator receives a circuit_open exit signal and must handle it — typically by recording the episode as a failure and escalating to the human.
Error Tracking
The circuit breaker maintains a frequency map of error messages. When any single error reaches sameErrorThreshold, it triggers an immediate circuit open:
// Error pattern detection
if (errorCounts[error] >= sameErrorThreshold) {
state = 'OPEN'
reason = `Same error repeated ${sameErrorThreshold} times: "${error}"`
}This catches infinite retry loops where the agent applies the same fix repeatedly without learning.