Detecting Silent Failure and Gating Changes

Lesson 2 of 4

Prove the Loop Is Advancing

Estimated time: 10 minutes

Prove the Loop Is Advancing

Long-running and autonomous loops can spin without progressing. Each iteration looks busy: tools are called, output is produced, tokens are spent. The loop is not stuck, it is merely not moving. The way to tell the difference is an invariant that must change as real progress is made.

Define the invariant before the loop starts

An invariant is a value that should strictly improve: items remaining, distance to a goal, number of satisfied checks. If two iterations leave the invariant identical, the loop is not progressing and should stop or change strategy rather than continue.

def stuck(prev, now):
    # no change in the measure of progress across an iteration
    return now >= prev

Hash the action, not the clock

If you detect repetition by comparing iterations, compare meaningful actions rather than timestamps or run ids, or every iteration looks different and the check never fires. Two calls that do the same thing are the same iteration even if their clocks differ.

Bound the loop as well as measure it

A progress invariant catches a loop that moves nothing. A cost or iteration ceiling catches a loop that moves slowly. Use both: the invariant is the correctness check, the ceiling is the safety net.