Originally written in French. Translated by AI — the meaning has been preserved, not the prose.
Main idea
A hook wired to the end of a conversation turn, whose job is precisely to call the assistant to have it summarize the exchange, triggers itself: the call it issues ends in turn, and that ending wakes the hook. The loop is not an implementation accident, it is the direct consequence of the setup — the automaton uses the very tool whose ending it watches.
The remedy isn't to avoid the call, but to make the automaton able to tell the triggers it caused apart from those coming from real work. Claude Code passes a stop_hook_active flag in the data sent to the script for this, and the script exits immediately when it sees it, before any processing.
That test goes first, before reading the transcript and before any model call. A safeguard placed after the expensive work protects nothing: the loop would already be consuming.
Why it matters
This is a failure you don't discover while designing, but while paying — in execution time, in billed calls, in sessions that never hand back control. Knowing it is structural lets you handle it at design time.
And the pattern shows up wherever a system reacts to its own effects: a database trigger that writes to the table it watches, a continuous integration pipeline that pushes a commit, a mail rule that replies in the thread it observes.
Nuances and limits
The distinction is only possible if the environment provides it. Without a signal of that kind, you have to manufacture one — a lock, a marker, a time window — and those substitutes fail as soon as two runs overlap.
And exiting on that signal has a cost: the internal exchange itself is never recorded.
Open questions
- How do you detect that a reflexive automation is looping, when its output is precisely to write nothing?