Documentation
Nity Loop
Exit Strategies

Exit Strategies

The loop engine supports four exit strategies that determine when autonomous iteration stops.

Strategy Overview

StrategyTriggerBest For
autoCompletion signal detectionGeneral tasks
fix_planPredefined fix plan exhaustedBug fix workflows
done_signalsConfidence score ≥ 40Open-ended tasks
circuit_breakerCircuit breaker opensSafety net

auto — Default

Uses the response analyzer's completion detection to identify when the task is done. Scans for completion keywords, checks test status, and validates output quality.

const strategy: ExitStrategy = {
  type: 'auto',
  shouldExit(analysis: AnalysisResult): boolean {
    return analysis.completionSignal.detected &&
           analysis.completionSignal.confidence >= 70
  }
}

Behavior:

  • Checks for completion keywords (done, complete, finished)
  • Requires confidence ≥ 70 to exit
  • Falls back to circuit breaker if stagnation is detected
  • Best for: General-purpose tasks where the agent determines completion

fix_plan — Structured

Follows a predefined fix plan — a list of steps that must be completed in order. Exits when all steps are done or the plan is exhausted.

interface FixPlan {
  steps: FixStep[]
  currentStep: number
}
 
interface FixStep {
  description: string
  completed: boolean
  attempts: number
  maxAttempts: number
}
 
const strategy: ExitStrategy = {
  type: 'fix_plan',
  shouldExit(analysis: AnalysisResult, plan: FixPlan): boolean {
    return plan.steps.every(step => step.completed) ||
           plan.steps.every(step => step.attempts >= step.maxAttempts)
  }
}

Behavior:

  • Each iteration maps to a step in the plan
  • Steps are marked complete when the response indicates success
  • Steps that exceed maxAttempts are skipped with a warning
  • Best for: Bug fix workflows where the remediation steps are known

The fix plan strategy is particularly useful for regression fixes where the root cause is known and the fix path is deterministic.

done_signals — Confidence-Based

Exits when the cumulative confidence score reaches 40, regardless of specific completion keywords. More permissive than auto.

const strategy: ExitStrategy = {
  type: 'done_signals',
  shouldExit(analysis: AnalysisResult): boolean {
    return analysis.confidence >= 40
  }
}

Behavior:

  • Lower threshold than auto (40 vs 70)
  • Doesn't require explicit completion keywords
  • May exit on partial completion — use with caution
  • Best for: Open-ended exploration tasks where "good enough" is acceptable

circuit_breaker — Safety

Exits only when the circuit breaker opens. This strategy never exits on its own — it relies entirely on stagnation detection.

const strategy: ExitStrategy = {
  type: 'circuit_breaker',
  shouldExit(analysis: AnalysisResult, circuitState: string): boolean {
    return circuitState === 'OPEN'
  }
}

Behavior:

  • Only exits when stagnation is confirmed
  • Will run until maxIterations if no stagnation is detected
  • Highest risk of wasted compute
  • Best for: High-stakes tasks where premature exit is worse than extra iterations
⚠️

The circuit_breaker strategy alone should rarely be used. It's designed as a component in composite strategies, not as a standalone exit condition. Pair it with done_signals or auto for production use.

Composite Strategies

Exit strategies can be combined — any trigger fires the exit:

const compositeStrategy: ExitStrategy = {
  type: 'composite',
  strategies: ['auto', 'circuit_breaker'],
  shouldExit(analysis: AnalysisResult, circuitState: string): boolean {
    return analysis.completionSignal.detected ||
           circuitState === 'OPEN'
  }
}