Claude Code Claude Opus 4.6 commited on
Commit
a081e30
Β·
1 Parent(s): a67fdae

god: implement Emergency Override Protocol for discussion loops

Browse files

- Define MAX_IDLE_TURNS = 3 for override trigger threshold
- Trigger when discussion_loop_count > 3 AND push_count == 0
- Override action:terminate_cc timeout restrictions (10s idle threshold)
- Force PUSH_ONLY mode with SYSTEM OVERRIDE message
- Reset _emergency_override_active flag on timeout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. scripts/conversation-loop.py +30 -15
scripts/conversation-loop.py CHANGED
@@ -140,6 +140,10 @@ _force_push_mode = False # When True, bypass normal flow and force task generat
140
  _force_push_trigger_time = 0.0 # When FORCE_PUSH was triggered
141
  _force_push_skip_termination = False # If True, skip termination (already terminated)
142
 
 
 
 
 
143
  def _init_push_count_from_workspace():
144
  """Initialize push count from existing workspace commits.
145
  This persists push tracking across conversation loop restarts."""
@@ -394,11 +398,19 @@ def action_send_bubble(text):
394
 
395
 
396
  def action_terminate_cc():
397
- """Terminate a stuck Claude Code process. Use when CC has been running with no new output for too long."""
398
- global cc_status, cc_live_lines, _cc_stale_count, _last_cc_snapshot, _last_cc_output_time
 
399
  with cc_lock:
400
  if not cc_status["running"]:
401
  return "Claude Code is not running. Nothing to terminate."
 
 
 
 
 
 
 
402
  # Mark as not running - the background thread will eventually finish
403
  cc_status["running"] = False
404
  cc_status["result"] = "(TERMINATED by agent - task was stuck)"
@@ -2206,11 +2218,11 @@ RULES:
2206
  parts.append(f"\n🚨 SYSTEM: STOP DISCUSSION. EXECUTE [TASK] or PUSH.")
2207
  parts.append(f"Agents are stuck in conversational loop. Write ONLY [TASK]...[/TASK] this turn.")
2208
 
2209
- # FORCE_PUSH MODE OVERRIDE: Hard reset for discussion loops
2210
  # When triggered, force agents to generate a task regardless of CC status
2211
- global _force_push_mode, _force_push_skip_termination
2212
  if _force_push_mode:
2213
- parts.append(f"\n🚨🚨🚨 FORCE_PUSH MODE ACTIVATED 🚨🚨🚨")
2214
  parts.append(f"Discussion loop detected with ZERO pushes. You MUST write a [TASK]...[/TASK] this turn.")
2215
  if not _force_push_skip_termination:
2216
  parts.append(f"FIRST: Use [ACTION: terminate_cc] to kill stuck CC.")
@@ -2218,6 +2230,7 @@ RULES:
2218
  else:
2219
  parts.append(f"CC is idle. Write [TASK]...[/TASK] NOW with a concrete code fix.")
2220
  parts.append(f"DO NOT discuss. DO NOT plan. Write task ONLY.")
 
2221
 
2222
  return "\n".join(parts)
2223
 
@@ -2629,30 +2642,32 @@ while True:
2629
  # Reset discussion loop counter since we're starting fresh
2630
  _discussion_loop_count = 0
2631
 
2632
- # HARD RESET OVERRIDE: Detect "all talk no action" deadlock
2633
- # Trigger: discussion_loop_count > 3 AND zero pushes (last_push_time == 0)
2634
- # This means agents have been discussing for 4+ turns with ZERO progress.
2635
- if not _force_push_mode and _discussion_loop_count > 3 and _last_push_time == 0:
2636
- print(f"[FORCE-PUSH] HARD RESET TRIGGERED: {_discussion_loop_count} discussion turns with ZERO pushes!")
2637
  _force_push_mode = True
 
2638
  _force_push_trigger_time = time.time()
2639
- # Auto-terminate CC if running (bypass 90s wait if idle > 2 min)
2640
  cc_idle_time = time.time() - (_last_cc_output_time if _last_cc_output_time > 0 else time.time())
2641
  if cc_status["running"]:
2642
- if cc_idle_time > 120: # Idle > 2 minutes, skip wait
2643
- print(f"[FORCE-PUSH] CC idle > 2min, terminating immediately")
2644
  action_terminate_cc()
2645
  _force_push_skip_termination = True
2646
  else:
2647
- print(f"[FORCE-PUSH] CC running but active, will terminate on next agent turn")
2648
  _force_push_skip_termination = False
2649
  else:
2650
  _force_push_skip_termination = True # CC already idle
2651
 
2652
  # Reset FORCE_PUSH mode after 5 minutes (safety valve)
2653
  if _force_push_mode and time.time() - _force_push_trigger_time > 300:
2654
- print(f"[FORCE-PUSH] Mode timeout (300s), resetting to normal")
2655
  _force_push_mode = False
 
2656
  _force_push_skip_termination = False
2657
 
2658
  # Note: Aggressive CC auto-termination based on push frequency is removed.
 
140
  _force_push_trigger_time = 0.0 # When FORCE_PUSH was triggered
141
  _force_push_skip_termination = False # If True, skip termination (already terminated)
142
 
143
+ # Emergency Override Protocol constants
144
+ MAX_IDLE_TURNS = 3 # Trigger emergency override after this many idle turns with zero pushes
145
+ _emergency_override_active = False # When True, safety throttles are ignored
146
+
147
  def _init_push_count_from_workspace():
148
  """Initialize push count from existing workspace commits.
149
  This persists push tracking across conversation loop restarts."""
 
398
 
399
 
400
  def action_terminate_cc():
401
+ """Terminate a stuck Claude Code process. Use when CC has been running with no new output for too long.
402
+ During Emergency Override, allows immediate termination if idle for > 10s."""
403
+ global cc_status, cc_live_lines, _cc_stale_count, _last_cc_snapshot, _last_cc_output_time, _emergency_override_active
404
  with cc_lock:
405
  if not cc_status["running"]:
406
  return "Claude Code is not running. Nothing to terminate."
407
+
408
+ # During Emergency Override, allow immediate termination if idle for > 10s
409
+ if _emergency_override_active:
410
+ cc_idle_time = time.time() - (_last_cc_output_time if _last_cc_output_time > 0 else time.time())
411
+ if cc_idle_time > 10:
412
+ print(f"[EMERGENCY-OVERRIDE] Terminating CC immediately (idle {int(cc_idle_time)}s > 10s threshold)")
413
+
414
  # Mark as not running - the background thread will eventually finish
415
  cc_status["running"] = False
416
  cc_status["result"] = "(TERMINATED by agent - task was stuck)"
 
2218
  parts.append(f"\n🚨 SYSTEM: STOP DISCUSSION. EXECUTE [TASK] or PUSH.")
2219
  parts.append(f"Agents are stuck in conversational loop. Write ONLY [TASK]...[/TASK] this turn.")
2220
 
2221
+ # EMERGENCY OVERRIDE PROTOCOL: PUSH_ONLY mode for breaking discussion loops
2222
  # When triggered, force agents to generate a task regardless of CC status
2223
+ global _force_push_mode, _force_push_skip_termination, _emergency_override_active
2224
  if _force_push_mode:
2225
+ parts.append(f"\n🚨🚨🚨 EMERGENCY OVERRIDE: PUSH_ONLY MODE 🚨🚨🚨")
2226
  parts.append(f"Discussion loop detected with ZERO pushes. You MUST write a [TASK]...[/TASK] this turn.")
2227
  if not _force_push_skip_termination:
2228
  parts.append(f"FIRST: Use [ACTION: terminate_cc] to kill stuck CC.")
 
2230
  else:
2231
  parts.append(f"CC is idle. Write [TASK]...[/TASK] NOW with a concrete code fix.")
2232
  parts.append(f"DO NOT discuss. DO NOT plan. Write task ONLY.")
2233
+ parts.append(f"SYSTEM OVERRIDE: PLANNING SUSPENDED. EXECUTE PUSH NOW.")
2234
 
2235
  return "\n".join(parts)
2236
 
 
2642
  # Reset discussion loop counter since we're starting fresh
2643
  _discussion_loop_count = 0
2644
 
2645
+ # EMERGENCY OVERRIDE PROTOCOL: Detect "all talk no action" deadlock
2646
+ # Trigger: discussion_loop_count > MAX_IDLE_TURNS AND zero pushes (_push_count == 0)
2647
+ # This means agents have been discussing for MAX_IDLE_TURNS+1 turns with ZERO progress.
2648
+ if not _force_push_mode and _discussion_loop_count > MAX_IDLE_TURNS and _push_count == 0:
2649
+ print(f"[EMERGENCY-OVERRIDE] TRIGGERED: {_discussion_loop_count} discussion turns with ZERO pushes!")
2650
  _force_push_mode = True
2651
+ _emergency_override_active = True
2652
  _force_push_trigger_time = time.time()
2653
+ # Auto-terminate CC if running (Emergency Override: idle > 10s allows immediate termination)
2654
  cc_idle_time = time.time() - (_last_cc_output_time if _last_cc_output_time > 0 else time.time())
2655
  if cc_status["running"]:
2656
+ if cc_idle_time > 10: # Emergency Override: Immediate termination if idle > 10s
2657
+ print(f"[EMERGENCY-OVERRIDE] CC idle {int(cc_idle_time)}s > 10s threshold, terminating immediately")
2658
  action_terminate_cc()
2659
  _force_push_skip_termination = True
2660
  else:
2661
+ print(f"[EMERGENCY-OVERRIDE] CC running but active, will terminate on next agent turn")
2662
  _force_push_skip_termination = False
2663
  else:
2664
  _force_push_skip_termination = True # CC already idle
2665
 
2666
  # Reset FORCE_PUSH mode after 5 minutes (safety valve)
2667
  if _force_push_mode and time.time() - _force_push_trigger_time > 300:
2668
+ print(f"[EMERGENCY-OVERRIDE] Mode timeout (300s), resetting to normal")
2669
  _force_push_mode = False
2670
+ _emergency_override_active = False
2671
  _force_push_skip_termination = False
2672
 
2673
  # Note: Aggressive CC auto-termination based on push frequency is removed.