Description
When a Claude Code session running under bmad-loop finishes its work and enters the "Leavening" phase (stop hooks execution), a re-entrant loop can occur that prevents the session from ever properly ending.
Steps to reproduce
- Configure a Claude Code project with Stop hooks that take more than ~5 seconds to complete (e.g., a hook that runs
gh CLI commands or a test suite)
- Run
bmad-loop run with a story
- Let the dev/review session complete its work and attempt to stop
What happens
- Session finishes work → enters "Leavening" phase → stop hooks begin executing
- Claude Code shows
running stop hooks… 0/N (the counter never progresses past 0)
- After ~5 seconds of hooks not completing, bmad-loop idle detection fires and writes "You appear idle in bmad-loop automation mode" into the TTY
- Claude sees this message as user input → tries to respond/explain → this triggers the Stop hooks AGAIN
- The cycle repeats: stop hooks run → idle detection → Claude responds → stop hooks run again → ...
Observed behavior
- The stop hook counter stays at
0/N indefinitely
bmad_loop_hook.py Stop completes successfully each iteration (Stop events are written to the run directory)
- But the session never transitions to
session-end in the journal
- The Claude process remains alive with an open API connection, stuck in this loop
- Tokens continue to be consumed as Claude re-processes the idle message each cycle
Expected behavior
Stop hooks should either:
- Complete (or timeout) before idle detection can fire, OR
- Idle detection should not inject messages into the TTY while stop hooks are in progress, OR
- The session should eventually end after a finite number of idle detection cycles
Environment
- bmad-loop 0.8.0
- Claude Code adapter
- macOS
Impact
Sessions that are functionally complete (all work done, verification passing, commits made) cannot terminate, consuming tokens and requiring manual intervention to kill the process.
Description
When a Claude Code session running under bmad-loop finishes its work and enters the "Leavening" phase (stop hooks execution), a re-entrant loop can occur that prevents the session from ever properly ending.
Steps to reproduce
ghCLI commands or a test suite)bmad-loop runwith a storyWhat happens
running stop hooks… 0/N(the counter never progresses past 0)Observed behavior
0/Nindefinitelybmad_loop_hook.py Stopcompletes successfully each iteration (Stop events are written to the run directory)session-endin the journalExpected behavior
Stop hooks should either:
Environment
Impact
Sessions that are functionally complete (all work done, verification passing, commits made) cannot terminate, consuming tokens and requiring manual intervention to kill the process.