The maxSameCallRepeats guard counted identical (name+arguments) tool calls across a run and tripped ErrToolLoop past the ceiling — regardless of whether each call made progress. This killed legitimate polling of long-running background jobs: code_exec_poll must be called with identical args (same job_id), so a render/encode that needs more than N polls was guillotined mid-flight even as each poll returned an advancing result (elapsed/status moving forward). Only count an identical call toward the trip when its RESULT is unchanged from the previous identical call. A call whose result keeps changing is progress and resets its count; a genuinely stuck call returning the same output still trips. This can never trip more than before, only less, and covers every idempotent poller with no per-tool configuration — matching the progress-over-usage thesis behind the stall-detection work. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01HgEuVfZJN9mhRhzEsMEVog