
    biSC                        d Z ddlZddlZddlZddlZddlZddlZddlmZmZ ddl	m
Z
  e
d      Zedz  dz  Z e
d      Zed	z  d
z  Zedz  dz  dz  Zedz  dz  Zed	z  dz  Zedz  Zedz  ZdZdZdZdZdefdZdefdZdefdZdededefdZ dedefdZ!defdZ"d)dede#fd Z$defd!Z%defd"Z&ded#edefd$Z'ded%efd&Z(d' Z)e*d(k(  r e)        yy)*u  
Genesis Auto-Respawn System — PostToolUse Hook (Layer 6 of Defense System)
==========================================================================
Monitors context usage and executes progressive CTM flush + respawn preparation.

This hook REPLACES the context_tracker.py thresholds with an action-oriented system
that actually performs the flush rather than just warning. It reads from the same
state file (data/context_state/current.json) written by genesis_statusline.sh.

Thresholds (Kinan Directive 2026-02-25):
  50% -> LOG: Warning + prepare CTM (no action, just awareness)
  65% -> CTM + RESPAWN: Execute full CTM flush AND trigger respawn
  70% -> HARD CTM + FORCED RESPAWN: Aggressive flush, mandatory immediate stop

Architecture:
  - StatusLine (Layer 1) writes context_state/current.json on every prompt
  - This hook (Layer 6) reads that file on every PostToolUse event
  - Deduplication via trigger bands (won't re-fire within same 5% band)
  - CTM flush writes to: MEMORY.md, hive/progress/session_N_handoff.md, supermemory
  - Respawn script at scripts/respawn_command_centre.sh handles session restart

Author: Genesis Defense System
Updated: 2026-02-25 — Kinan lowered thresholds: 65% CTM+respawn, 70% hardCTM+respawn
    N)datetimetimezone)Pathz/mnt/e/genesis-systemdatacontext_statezI/home/authentic88/.claude/projects/-mnt-e-genesis-system/memory/MEMORY.mdhiveprogresszmcp-serverssupermemoryzsave.shobservabilitysession_recoveryzrespawn_requested.flagzauto_respawn_triggers.jsonl2   A   F      returnc                      t         dz  } | j                         si S 	 t        | d      5 }t        j                  |      cddd       S # 1 sw Y   yxY w# t
        $ r i cY S w xY w)z2Read context state from StatusLine-generated file.zcurrent.jsonrN)	STATE_DIRexistsopenjsonload	Exception)
state_filefs     3/mnt/e/genesis-system/.claude/hooks/auto_respawn.pyread_context_stater   ?   sa    ^+J	*c" 	 a99Q<	  	  	  	s-   A A	A AA A A"!A"c                      t               } | j                  dd      }|r|S t        j                  j                  dd      S )z1Get current session ID from state or environment.
session_id CLAUDE_SESSION_IDunknown)r   getosenviron)statesids     r   get_session_idr(   K   s8     E
))L"
%C

::>>-y99    c                     t         j                  dd       t        t         j                  d            } d}| D ]G  }t	        j
                  d|j                        }|s&t        |j                  d            }||kD  sF|}I |dz   S )z5Determine session number from existing handoff files.Tparentsexist_okzsession_*_handoff.mdr   zsession_(\d+)_handoff\.md   )	HANDOFF_DIRmkdirlistglobresearchnameintgroup)existingmax_nr   matchns        r   get_session_numberr<   T   s    dT2K$$%;<=HE 		6?EKKN#A5y 19r)   pctactionc                    t         j                         syt        | t        z        t        z  }t	               }	 t        t         d      5 }|D ]m  }t        j                  |j                               }|j                  d      |k(  s;|j                  d      |k(  sP|j                  d      |k(  se ddd       y 	 ddd       y# 1 sw Y   yxY w# t        $ r Y yw xY w)z8Check if this action was already triggered in this band.Fr   r>   bandr   NT)TRIGGER_LOGr   r6   
DEDUP_BANDr(   r   r   loadsstripr#   r   )r=   r>   r@   r   r   lineentrys          r   already_triggeredrG   b   s    sZ :-D!J	+s# 	 q  

4::<0IIh'61		&)T1		,/:=	  	  	  	    sM   C 
=CCC2C3C <C>C CC C 	CCc                    t        | t        z        t        z  }t        j                  dd       	 t	        j
                  t        j                        j                         |t        | d      |t               d}t        t        d      5 }|j                  t        j                  |      dz          ddd       y# 1 sw Y   yxY w# t         $ r Y yw xY w)z0Record that we triggered an action at this band.Tr+   r.   )	timestampr>   
percentager@   r   a
N)r6   rB   r   r0   r   nowr   utc	isoformatroundr(   r   rA   writer   dumpsr   )r=   r>   r@   rF   r   s        r   log_triggerrS   u   s    sZ :-DOOD4O0!hll3==?Q-(*
 +s# 	.qGGDJJu%,-	. 	. 	. s0   AC (B<3C <CC C 	CCc                  :   	 t         dz  } | j                         rat        | d      5 }t        j                  |      }|j                  dd      |j                  dd      |j                  dd      dcddd       S ddddS # 1 sw Y   xY w# t        $ r Y w xY w)	z2Read active agent info from observability metrics.zmetrics.jsonr   agents_activer   agent_spawnsagent_stops)active_counttotal_spawnstotal_stopsN)
EVENTS_DIRr   r   r   r   r#   r   )metrics_filer   metricss      r   get_active_agentsr^      s    !N2 lC( A))A,$+KK$C$+KK$B#*;;}a#@  qCC   s)   %B AB2	B BB 	BBlimitc                 N   g }	 t         dz  }|j                         rt        |d      5 }|j                  dd       |j	                         }t        |d      }|j                  t        d||z
               |j                         j                  dd      j                         j                  d	      }d
d
d
       |  d
 D ]5  }	 |j                  t        j                  |j                                      7 |S # 1 sw Y   IxY w# t        $ r Y Qw xY w# t        $ r Y |S w xY w)z*Read recent events from observability log.events.jsonlrbr      i zutf-8replace)errorsrL   N)r[   r   r   seektellminmaxreaddecoderD   splitappendr   rC   r   )r_   eventsevents_filer   	file_size	read_sizelinesrE   s           r   get_recent_eventsrs      s   F >1k4( WAq!FFH		62	s1i)345	BHHJPPQUVW ufg MM$**TZZ\":; MW W !  MsM   %D BC<4D 2D8D <DD 	DD DD 	D$#D$c                      	 t         dz  } | j                         r(t        | d      5 }t        d |D              cddd       S 	 y# 1 sw Y   yxY w# t        $ r Y yw xY w)zCount compaction events.zcompaction_log.jsonlr   c              3       K   | ]  }d   yw)r.   N ).0_s     r   	<genexpr>z'get_compaction_count.<locals>.<genexpr>   s     .1.s   Nr   )r   r   r   sumr   )log_filer   s     r   get_compaction_countr|      sn    55??h$ ).a.() ) 
 	)   s-   %A A	A A
A A 	AAc                  :    t               } | j                  dd      S )z$Get current session cost from state.cost_usdr   )r   r#   )r&   s    r   get_costr      s     E99Z##r)   trigger_levelc                    t        j                  t        j                        }t	               }t               }t               }t               }t               }t               }t        d      }	t        j                  dd       t        d| dz  }
g }|	dd D ]M  }|j                  d|j                  d	d
            }|j                  dd
      }|j                  d| d|        O dj                  g d| d|j!                          d|j#                          d| d| dd|j                  dd
       d|dd| d| d| dd|j                  dd       d|j                  d d       d!|j                  d"d       d#|rt%        d$      j                  |      nd% d&t'        j(                  |d'(       d)| d*| dd+|d,k(  rd-nd. d/      }	 t+        |
d0      5 }|j-                  |       ddd       d3}t0        j3                         rW	 d4| d5| dd6| d7|dd8|j                  dd       d9| d:| d}t5        j6                  d;t9        t0              |d<gd$dd=       d}	 t<        j                  dd       |j#                         d>|t?        | d?      |||j                  dd      |t9        |
      |d@
}t<        dAz  }t+        |dB      5 }|j-                  t'        j(                  |      dCz          ddd       t9        |
      ||dDS # 1 sw Y   !xY w# t.        $ r}d1d2| icY d}~S d}~ww xY w# t4        j:                  t.        f$ r Y w xY w# 1 sw Y   axY w# t.        $ r Y ow xY w)Ea  
    Execute the full CTM (Commit To Memory) flush.

    Writes:
    1. Session handoff file to hive/progress/session_N_handoff.md
    2. Saves to supermemory via save.sh (best-effort, non-blocking)
    3. Logs the flush event

    Does NOT modify MEMORY.md directly -- that requires Claude to do it
    via the additionalContext instruction returned by this hook.

    Returns a summary dict of what was written.
       Tr+   session_z_handoff.mdiNtool
event_type?rI   z- z @ r    z
# Session z5 Handoff
## Auto-generated by Auto-Respawn System at z threshold

**Generated**: z
**Session ID**: z
**Context Usage**: z.1fz%
**Remaining (actual)**: actual_freez%
**Session Cost**: $z.2fz
**Compaction Events**: z
**Trigger Level**: z (threshold crossed at z%%)

## Agent Status
- Active agents: rX   r   z
- Total spawns this session: rY   z
- Total stops this session: rZ   z$

## Recent Tool Activity (last 10)

   zNo recent activity recorded.ar  

## Respawn Instructions
1. Read MEMORY.md -- war room status has the active mission
2. Check hive/progress/ for this and prior handoff files
3. Check hive/session_recovery/LATEST.md for heartbeat state
4. Check data/observability/events.jsonl for full event trail
5. Resume the active mission immediately -- no re-orientation needed

## Context State Snapshot
```json
rc   indentzp
```

## Auto-Respawn Notes
- This handoff was triggered automatically by the auto-respawn defense system
- The z threshold (z%) was crossed
- respawnz=RESPAWN WAS REQUESTED -- session should restart automaticallyz.Session is still active but approaching limitsz=
- Next session should resume from MEMORY.md war room status
werrorzFailed to write handoff: Fz[CTM-FLUSH session-z] Context at z%, trigger=z, cost=$z, agents_active=z, compactions=z$. Handoff at: hive/progress/session_bashz	ctm-flush)timeoutcapture_outputtext	ctm_flushr.   )
rI   r   r   rJ   r   session_numberrU   r~   handoff_filesupermemory_savedra   rK   rL   )r   r   r   ) r   rM   r   rN   r(   r<   r^   r   r|   r   rs   r/   r0   r#   rm   joinupperrO   chrr   rR   r   rQ   r   SUPERMEMORY_SAVEr   
subprocessrunstrTimeoutExpiredr[   rP   )r=   r   rM   r   session_numagentsr   compactionscostrecentr   tool_summaryevtr   tshandoff_contentr   er   summaryeventro   s                         r   execute_ctm_flushr      s    ,,x||
$C!J$&K F&(M&(K:Dr"F dT28K=!DDL Lcd| 0wwvsww|S9:WW[#&bc"./0
$ $* $[M $ 2- $-:-@-@-B,C$D$  $!$ 	$	$
 9$
$ '**=#>?$@$ :$$ $}$%$ "?$ #:$ ;>c$C$ **^Q/0$1$ %jj;<$=$ $ZZq9:$;$"  ,Rl1O P#$"Q#$8 M!$ %9$8&9$B oC$B "C$B #&cC$B+C$D GTW`F`B  gW  XE$DXE$OL:,$ 	%GGO$	%  	%k] 3!#Yk- Ac
"26::na3P2Q R*m ,55@M	N  NN-.E#	 !%
5%*Q-$)#ZZ:-!2
 !>1+s# 	.qGGDJJu%,-	. L)%. _	% 	% :4QC899:* ))95 		&	. 	. st   ,L6 8L)
L6 )AM  A*M> *(M2M> )L3.L6 6	M?MMMM/.M/2M;7M> >	N
	N
r   c                 n   t         j                  dd       	 t        j                  t        j
                        j                         t               |t        | d      dt         dd}t        t        d      5 }t        j                  ||d	       d
d
d
       y
# 1 sw Y   y
xY w# t        $ r Y y
w xY w)zx
    Write a flag file that the respawn script can detect.
    Also writes the respawn command to a known location.
    Tr+   r.   zContext usage exceeded %)rI   r   r   context_pctreasonr   rc   r   N)r   r0   r   rM   r   rN   rO   r(   rP   RESPAWN_THRESHOLDr   RESPAWN_FLAGr   dumpr   )r=   r   	flag_datar   s       r   write_respawn_flagr   K  s    
 OOD4O0!hll3==?(*) a=/0A/B!D
	 ,$ 	.IIi1-	. 	. 	. s0   A!B( :BB( B%!B( %B( (	B43B4c                  $   	 t        j                  t        j                  j	                               } t               }|j                  dd      }|j                  dd      }|dk(  rt        t        j                  i              y i }|t        k\  rkt        |d      st        |d       t        |d      }|j                  dd      }t        ||       d|d	d
|d	d| d|j                  d      rdnd d	|d<   n|t         k\  rut        |d      st        |d       t        |d      }|j                  dd      }t        ||       d|d	d
|d	d| d|j                  d      rdnd d|d	dt         d|d<   n=|t"        k\  r4t        |d      s(t        |d       d|d	d|d	dt          dt         d	|d<   t        t        j                  |             y # t         j
                  t        f$ r! t        t        j                  i              Y y w xY w)Nused_percentager   r   d   hard_respawnr   r   z&HARD CTM + FORCED RESPAWN: Context at z.0fz% (actual free: uq   %). This is the HARD threshold — session MUST end NOW. CTM flush EXECUTED — handoff at hive/progress/session_z_handoff.md. Supermemory: r   savedzfailed (non-critical)u  . 

FORCED STOP PROTOCOL — DO THIS IMMEDIATELY:
1. UPDATE MEMORY.md WAR ROOM STATUS — active mission, agents, decisions, blockers, next actions
2. STOP all background agents — note their IDs
3. DO NOT start any new work — session is dying
4. Tell Kinan: 'Hard CTM complete. Session respawning.'
5. The respawn script is at: scripts/respawn_command_centre.sh

This is NON-NEGOTIABLE. The session MUST die and respawn. Continuing past 70% risks autocompaction + thinking block corruption.additionalContextctm_respawnz$CTM + RESPAWN TRIGGERED: Context at u<   %). CTM flush EXECUTED — handoff at hive/progress/session_u  . 

RESPAWN PROTOCOL — BEGIN WRAP-UP:
1. UPDATE MEMORY.md WAR ROOM STATUS — mission, agents, decisions, blockers, next actions
2. Note running agent IDs and expected output paths
3. Wrap current task to a stable checkpoint
4. Tell Kinan: 'CTM complete. Respawn ready at z`%.'
5. Respawn script: scripts/respawn_command_centre.sh

Hard CTM + forced respawn triggers at u6   %. Wrap up NOW — do not wait for the hard threshold.warnzCONTEXT AWARENESS: z% used (actual free: z"%). CTM + respawn will trigger at z %. Hard CTM + forced respawn at zF%. Consider starting to save important state to MEMORY.md proactively.)r   rC   sysstdinrj   JSONDecodeErrorr   printrR   r   r#   HARD_RESPAWN_THRESHOLDrG   rS   r   r   CTM_RESPAWN_THRESHOLDWARN_THRESHOLD)
hook_inputr&   r=   r   resultflush_resultr   s          r   mainr   c  sy   ZZ		 01
  E
))%q
)C))M3/K axdjjnF
 $$ n5^, -S.AL&**+;SAK sK0 9S	AQR]^aQb cKKV- X +7+;+;<O+PVmn 	oXY &'& 
%	% m4]+ -S-@L&**+;SAK sK0 7s3i?OP[\_O` aKKV- X +7+;+;<O+PVmn oB CFc K99O8P QFG &'$ 
	 f-V$ &c#Y.CKPSCT U11F0G H00F/G HVW &' 
$**V
s   ), djjns   1G 7HH__main__)   )+__doc__r   r   r$   r   r3   timer   r   pathlibr   GENESIS_ROOTr   MEMORY_FILEr/   r   r[   RECOVERY_DIRr   rA   r   r   r   rB   dictr   r   r(   r6   r<   floatboolrG   rS   r^   r1   rs   r|   r   r   r   r   __name__rv   r)   r   <module>r      s  2   	  	  '  +,6!O3	^_V#j0-/-?)K F"_4
f$'993377    
	D 	: :C 5 # $ &U C ,D4 D"S $ ,	c 	$% $|5 | | |FE  0\~ zF r)   