Summary
In an autonomous-loop session (invoked via a project skill's slash command with a stated success condition, e.g. `/housecarl `), the Stop-hook goal-condition evaluator re-fires identical feedback on every single subsequent turn, indefinitely, with no mechanism to acknowledge that the operator has explicitly overridden the goal and no way for the assistant to durably suppress it.
Steps to reproduce
- Invoke an autonomous-loop skill via slash command with an explicit numeric success condition (e.g. "fight until fewer than N open issues remain").
- Let the agent make partial progress toward the goal, dispatching sub-agents/teammates.
- As the operator, explicitly instruct the agent to stand down before the numeric condition is met.
- Watch the agent fully comply: stop all sub-agents, close out tracking state, call the loop's own "stop" tool/affordance (in this case
ScheduleWakeup({stop: true}), which correctly reports the loop as stopped and cancels pending wakeups).
- On the very next turn boundary (and every one after), a "Stop hook feedback" message re-appears, quoting the original goal text and asserting the numeric condition was not satisfied — worded almost identically each time, sometimes explicitly acknowledging the operator's stand-down order in the same message, but treating it as irrelevant to the check ("The operator's override instruction is a separate governance decision, but does not retroactively satisfy the numerical condition").
- This repeats without limit, once per turn, even though the agent has confirmed (via the harness's own tools) that no cron jobs and no pending scheduled wakeups remain for this goal.
Expected behavior
Once the agent has called whatever tool ends a dynamic autonomous loop (here, ScheduleWakeup({stop:true}), which itself reports success and "no further dynamic-loop wakeups scheduled"), the separate Stop-hook goal-condition evaluator should stop firing for that same goal — or at minimum, an explicit operator override/stand-down instruction in the transcript should be recognized as terminating the evaluation, not just noted and then disregarded every time.
Actual behavior
The evaluator appears to be a distinct mechanism from the loop's own stop/cancel affordance, unaware that the loop was deliberately ended, and it re-fires the identical assessment on every subsequent turn with no decrement, cooldown, or acknowledgment path — burning the operator's tokens and attention indefinitely on a check that both the agent and the operator have already resolved. The operator eventually had to intervene directly ("stop wasting my god damn tokens and stand down") because the agent had no available tool to suppress the recurring hook.
Impact
- Wastes real operator token budget/attention on a session that both parties have already agreed is finished.
- No path within the conversation (checked:
ScheduleWakeup({stop:true}), CronList/CronDelete — no jobs found) let the agent silence it.
- Makes an explicit human stand-down instruction feel ineffective, since the automated evaluator keeps re-litigating a decision that's no longer in question.
Suggested fix
- The Stop-hook goal-condition evaluator should observe the same "loop stopped" signal that
ScheduleWakeup({stop: true}) produces, and stop evaluating/firing for that goal once it's been explicitly cancelled.
- Alternatively, provide an explicit tool/affordance for the agent (or a hook config) to mark a stated autonomous-loop goal as operator-overridden/abandoned, distinct from merely reporting that the numeric condition wasn't met.
Summary
In an autonomous-loop session (invoked via a project skill's slash command with a stated success condition, e.g. `/housecarl `), the Stop-hook goal-condition evaluator re-fires identical feedback on every single subsequent turn, indefinitely, with no mechanism to acknowledge that the operator has explicitly overridden the goal and no way for the assistant to durably suppress it.
Steps to reproduce
ScheduleWakeup({stop: true}), which correctly reports the loop as stopped and cancels pending wakeups).Expected behavior
Once the agent has called whatever tool ends a dynamic autonomous loop (here,
ScheduleWakeup({stop:true}), which itself reports success and "no further dynamic-loop wakeups scheduled"), the separate Stop-hook goal-condition evaluator should stop firing for that same goal — or at minimum, an explicit operator override/stand-down instruction in the transcript should be recognized as terminating the evaluation, not just noted and then disregarded every time.Actual behavior
The evaluator appears to be a distinct mechanism from the loop's own stop/cancel affordance, unaware that the loop was deliberately ended, and it re-fires the identical assessment on every subsequent turn with no decrement, cooldown, or acknowledgment path — burning the operator's tokens and attention indefinitely on a check that both the agent and the operator have already resolved. The operator eventually had to intervene directly ("stop wasting my god damn tokens and stand down") because the agent had no available tool to suppress the recurring hook.
Impact
ScheduleWakeup({stop:true}),CronList/CronDelete— no jobs found) let the agent silence it.Suggested fix
ScheduleWakeup({stop: true})produces, and stop evaluating/firing for that goal once it's been explicitly cancelled.